Java-сокет, дающий преждевременное завершение потока - PullRequest
1 голос
/ 02 февраля 2011

Я настраиваю комет-сервер, который подключается к XMPP-серверу.Вот как это происходит:

Клиент подключается к серверу комет и, среди прочего, открывается сокетное соединение:

try {
        radio = new Socket("server", 5222);
        out = new PrintWriter(radio.getOutputStream(), true);
        in = new BufferedReader(new InputStreamReader(radio.getInputStream()));
    } catch (UnknownHostException e) {
        System.out.println("Unknown host: "+e);
        error = e.toString();
    } catch(IOException e) {
        System.out.println("IO error: "+e);
        error = e.toString();
    }

Далее запускается поток, который ожидаетданные из сокета:

public void run() {
        System.out.println("Thread started.");
        String data;
        String error;
        Client remote;
        Client client;
        while(!done) {
            data = this.output();
            remote = bayeux.getClient(remoteId);
            client = bayeux.getClient(clientId);
            if(data!=null) {
                Map<String, Object> packet = new HashMap<String, Object>();
                packet.put("xml", data);
                remote.deliver(client, "/radio/from", packet, null);
            }
            error = this.error();
            if(error!=null) {
                Map<String, Object> packet = new HashMap<String, Object>();
                packet.put("details", error);
                remote.deliver(client, "/radio/error", packet, null);
            }
            /* try { 
                Thread.sleep(500); 
            }  
            catch (InterruptedException e ) {
                System.out.println("Interrupted!"); } */
        }

        try {
            in.close();
            out.close();
            radio.close();
        } catch(IOException e) {
            System.out.println("Error disconnecting: "+e);
            error = e.toString();
        }
        System.out.println("Thread stopped.");
    }

    public String output() {
        try {
            String data = in.readLine();
            System.out.println("From: "+data);
            if(data==null) {
                System.out.println("End of stream!");
                try {
                    Thread.currentThread().sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                //error = "End of stream.";
                //this.disconnect();
            }
            return data;
        } catch (IOException e) {
            error = e.toString();
            System.out.println("IO error! "+e);
        }
        return null;
    }

Любые входные данные, полученные от клиента, перенаправляются на сервер XMPP:

    public void input(String xml) {
        System.out.println("To: "+xml);
        out.println(xml);
    }

Так вот, где возникает проблема. Клиент открывает соединение иотправляет правильный XML на сервер XMPP для запуска потока.in.readLine(); зависает, как и положено, до получения ответа от сервера.Как только он получен, in.readLine(); начинает возвращать ноль, снова и снова.Этого не должно быть;он должен зависать, пока не получит данные.Кажется маловероятным, что сервер закрылся на мне, он не отправил </stream:stream>, чтобы сигнализировать об окончании потока XMPP.Есть идеи, в чем может быть проблема?

Спасибо за помощь!

1 Ответ

0 голосов
/ 03 февраля 2011

Имейте в виду, что соединение XMPP может и даст вам неполные разделы или несколько разделов за одно чтение. Если ваше соединение COMET ожидает, что вы передаете это правильно сформированный XML, у вас будут проблемы. Кроме того, XMPP не завершается символом новой строки, поэтому я не уверен, почему вы ожидаете, что readLine() будет ужасно полезным.

Далее, вы делаете синхронный ввод / вывод на двух разных сокетах в одном потоке? Звучит как рецепт для тупика. Если вы настаиваете на том, чтобы идти по этому пути (вместо того, чтобы просто использовать BOSH ), я настоятельно рекомендую вам использовать NIO вместо взлома сна.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...