2011-02-02 66 views
1

我正在設置連接到XMPP服務器的彗星服務器。下面是它的下降:Java套接字提前過期結束

一個客戶機連接與彗星服務器,除其他事項外,一個插座連接打開:

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();開始返回null,一遍又一遍。這不應該發生;它應該掛起直到它收到數據。服務器似乎不太可能關閉我,它還沒有發送</stream:stream>來表示XMPP流的結束。任何想法可能是什麼問題?

謝謝你的幫助!

+0

你說服務器關閉連接不太可能,但爲了安全起見,你真的檢查過readLine()返回null後radio.isConnected()的返回結果嗎? – 2011-02-02 19:15:38

+0

您不僅僅使用BOSH(http://xmpp.org/extensions/xep-0206.html),這太糟糕了,或者您可以使用現成的客戶端,服務器或兩者兼有的東西。 – 2011-02-02 21:03:56

回答

0

請記住,XMPP連接可以並且會在一次讀取中爲您提供不完整的節或多節。如果你的COMET連接期望你傳遞的是格式良好的XML,你將會遇到問題。另外,XMPP不是換行符終止的,所以我不確定爲什麼你期望readLine()非常有用。

接下來,你是否在同一個線程上的兩個不同套接字上進行同步I/O?聽起來像是僵局的祕訣。如果你堅持走這條路(而不是僅僅使用BOSH),我強烈要求你使用NIO,而不是你的睡眠破解。