1. Вы находитесь в сообществе Rubukkit. Мы - администраторы серверов Minecraft, разрабатываем собственные плагины и переводим на различные языки плагины наших коллег из других стран.
    Скрыть объявление
Скрыть объявление
В преддверии глобального обновления, мы проводим исследования, которые помогут нам сделать опыт пользования форумом ещё удобнее. Помогите нам, примите участие!

Помогите Конфликт return в асинхронном выполнении

Тема в разделе "Разработка плагинов для новичков", создана пользователем Bars, 25 мар 2016.

Статус темы:
Закрыта.
  1. Автор темы
    Bars

    Bars Старожил Девелопер Пользователь

    Баллы:
    173
    Ошибка выделена на скриншоте. Я конечно понимаю что этот return уже не в своей функции, но как-то надо исправлять... Подскажите, а)

    Код:
        String sendPost(final String urlParameters) throws Exception {
            getServer().getScheduler().runTaskAsynchronously(this, new Runnable(){
                @Override
                public void run() {
                    try {
                        String url = "http://site.ru/script.php";
                        URL obj = new URL(url);
                        HttpURLConnection con = (HttpURLConnection) obj.openConnection();
    
                        // Add request header
                        con.setRequestMethod("POST");
                        con.setRequestProperty("User-Agent", "Mozilla/5.0");
                        con.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
    
                        // Send post request
                        con.setDoOutput(true);
                        DataOutputStream wr = new DataOutputStream(con.getOutputStream());
                        wr.writeBytes(urlParameters);
                        wr.flush();
                        wr.close();
    
                        /*int responseCode = con.getResponseCode();
                        System.out.println("\nSending 'POST' request to URL : " + url);
                        System.out.println("Post parameters : " + urlParameters);
                        System.out.println("Response Code : " + responseCode);*/
    
                        BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
                        String inputLine;
                        StringBuffer response = new StringBuffer();
    
                        while ((inputLine = in.readLine()) != null) { response.append(inputLine); }
                        in.close();
    
                        return response.toString();
                    } catch (Exception e1) {}
                }
            }
        }
     

    Вложения:

    • async.png
      async.png
      Размер файла:
      38,6 КБ
      Просмотров:
      42
  2. Reality_SC

    Reality_SC Старожил Пользователь

    Баллы:
    123
    Имя в Minecraft:
    Reality_SC
    Ну так просто убери его и все? Зачем что-то возвращать из void метода?
     
  3. Автор темы
    Bars

    Bars Старожил Девелопер Пользователь

    Баллы:
    173
    Надо вернуть ответ от сервера чтобы отправить игроку
     
  4. Reality_SC

    Reality_SC Старожил Пользователь

    Баллы:
    123
    Имя в Minecraft:
    Reality_SC
    Если результат нужен, и его нужно где-то использовать, то:
    Создаешь интерфейс с методом, принимающем String response, например run.
    В параметры твоего метода добавляешь такой объект, final.
    В конце вместо return делаешь вызов nextActions.run(response.toString()).
    Там, где используешь твой метод, Создаешь имплементации твоего нового интерфейса с тем кодом, который работает с ответом.
     
  5. Jampire

    Jampire Старожил Пользователь

    Баллы:
    173
    Skype:
    jampire-h
    Имя в Minecraft:
    Jampire
    ты пускаешь асинхронный таск и пытаешься из него что-то ретурнить. бред же, ибо как ты уже сказал - это другая функция.

    хорошим вариантом будет создание интерфейса с обработкой ответа от таска, но лучше банально написать таск в отдельном классе (имплемент Runnable) и уже в самом классе описать метод sendPost и отдельно вызвать его из метода run()

    нормально ретурн делать можно лишь из Callable тасков. но это синхронные штуки, совершенно для других задач
     
    Последнее редактирование: 25 мар 2016
  6. Автор темы
    Bars

    Bars Старожил Девелопер Пользователь

    Баллы:
    173
    Я не совсем понимаю на практике
     
  7. Jampire

    Jampire Старожил Пользователь

    Баллы:
    173
    Skype:
    jampire-h
    Имя в Minecraft:
    Jampire
    вчера немного не так понял то, что тебе нужно. нужно примерно так это реализовать
    Код:
    public class Test implements Runnable {
    
        private String response = null;
     
        @Override
        public void run() {
            this.response = sendPost("params");
        }
     
        public String getResponse() {
            return this.response;
        }
     
        public String sendPost(String params) {
            return "response";
        }
    }
    

    примерно то, что тебе нужно.
    запускаешь это дело извне с помощью


    Код:
    Test test = new Test();
    Bukkit.getScheduler().runTaskAsynchronously(this, test);
    через некоторое время проверяешь ответ у объекта test.

    Код:
    test.getResponse()
    вместо сохранения ответа ты можешь сразу передать его в нужный тебе метод после выполнения таска. в таком случае его даже хранить не прийдеться.
     
  8. Reality_SC

    Reality_SC Старожил Пользователь

    Баллы:
    123
    Имя в Minecraft:
    Reality_SC
    Ну или просто сделать в коде из первого поста рядом другой метод onWebServerAnswerAsync(final String response), и в том месте, где return, вызывать его.
    В теле метода пишешь баккит.шедулер.runTask(new Runnable() { Код, который посылает месагу игрокам });
    Все.

    Если месага нужна определенным игрокам, проводишь кому через отдельную final переменную в аргументах обоих методов!
     
  9. Jampire

    Jampire Старожил Пользователь

    Баллы:
    173
    Skype:
    jampire-h
    Имя в Minecraft:
    Jampire
    решение хорошее, но зависит от 8й джавы, которую сейчас использует максимум 10% серверов. если тс пишет плагин для паблика - люди будут страдать из за такого решения =)
     
  10. Автор темы
    Bars

    Bars Старожил Девелопер Пользователь

    Баллы:
    173
    Есть идея записывать ответ в отдельную глобальную переменную String answer, которая не final (на примере в скриншоте это fileList). Но ответ ведь приходит с задержкой. Как дождаться этого ответа и только потом выполнить код после sendPost(...)?
     

    Вложения:

  11. Code

    Code Старожил Пользователь

    Баллы:
    123
    Имя в Minecraft:
    _Gizmo
    зачем тебе рунабл, если ты все равно хочешь дождаться ответа?
     
  12. Автор темы
    Bars

    Bars Старожил Девелопер Пользователь

    Баллы:
    173
    Очень-очень сильно нагружает сервер, подумал тут асинхрон поможет
     
  13. Code

    Code Старожил Пользователь

    Баллы:
    123
    Имя в Minecraft:
    _Gizmo
    тогда тебе надо сделать что-то типа того, что написал Jampire, только не ответ сохранять и потом смотреть, а передать в этот ранабл игрока, которому надо ответ послать. и просто в конце run() допиши отправлялку ответа.,
     
  14. Автор темы
    Bars

    Bars Старожил Девелопер Пользователь

    Баллы:
    173
    Насчет ответа игроку передумал уже, ведь из асинхрона нельзя задействовать BukkitAPI. Мне надо получить список файлов с сервера (в виде строки) обратно в функцию
     
  15. fall.us

    fall.us Активный участник Пользователь

    Баллы:
    76
    Имя в Minecraft:
    fallus
    Как вариант, используйте систему событий(events) Bukkit. Или напишите собственную.
     
    Последнее редактирование: 27 мар 2016
  16. Reality_SC

    Reality_SC Старожил Пользователь

    Баллы:
    123
    Имя в Minecraft:
    Reality_SC
    Что за бред, из асинхрона вызываешь синхрон на ближайший такт, и всё.
     
  17. Code

    Code Старожил Пользователь

    Баллы:
    123
    Имя в Minecraft:
    _Gizmo
    угу, шедулишь синхронное событие еще через один ранабл и готово)
     
  18. Reality_SC

    Reality_SC Старожил Пользователь

    Баллы:
    123
    Имя в Minecraft:
    Reality_SC
    Код:
        void x(final Player player)
        {
            new Thread()
            {
                @Override
                public void run()
                {
                    try
                    {
                        String filelist = sendPost("URL PARAMS");
                        // TO DO HERE
                        Bukkit.getScheduler().runTask(BukkitPluginMain.this, new Runnable()
                        {
                            @Override
                            public void run() {
                                player.sendMessage("BLA BLA BLA!!!");
                            }
                        });
                    } catch(final Exception ex) {
                        Bukkit.getScheduler().runTask(BukkitPluginMain.this, new Runnable()
                        {
                            @Override
                            public void run() {
                                player.sendMessage("error: " + ex);
                            }
                        });
                    }
                }
            }.start();
        }
        public String sendPost(final String urlParameters) throws Exception
        {
            String url = "http://site.ru/script.php";
            URL obj = new URL(url);
            HttpURLConnection con = (HttpURLConnection) obj.openConnection();
    
            // Add request header
            con.setRequestMethod("POST");
            con.setRequestProperty("User-Agent", "Mozilla/5.0");
            con.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
    
            // Send post request
            con.setDoOutput(true);
            DataOutputStream wr = new DataOutputStream(con.getOutputStream());
            wr.writeBytes(urlParameters);
            wr.flush();
            wr.close();
    
            /*int responseCode = con.getResponseCode();
            System.out.println("\nSending 'POST' request to URL : " + url);
            System.out.println("Post parameters : " + urlParameters);
            System.out.println("Response Code : " + responseCode);*/
            BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
            String inputLine;
            StringBuffer response = new StringBuffer();
    
            while ((inputLine = in.readLine()) != null)
                response.append(inputLine);
            in.close();
    
            return response.toString();
        }
     
  19. Jampire

    Jampire Старожил Пользователь

    Баллы:
    173
    Skype:
    jampire-h
    Имя в Minecraft:
    Jampire
    из асинхрона можно задействовать BukkitAPI, используя Scheduler.runSyncMethod
     
  20. Автор темы
    Bars

    Bars Старожил Девелопер Пользователь

    Баллы:
    173
    Всем спасибо ;)
     
Статус темы:
Закрыта.

Поделиться этой страницей