2017-05-05 109 views
3

我一直在研究一個簡單的UPnP客戶端實現,但我在接收事件時遇到了問題。爲了在我發送的消息中嘗試查找錯誤,我使用CLing測試了我的用例(這是一個非常棒的庫,但它依賴於Java 1.5,而我只能訪問1.4),但是我無法找到它的信息和我的之間有任何有意義的區別未收到或未收到UPnP事件

我正在訂閱/ MediaRenderer/AVTransport/Event events,測試以查看我是否可以獲取最新的TransportState。

這裏是我的測試代碼:

private static final String PLAYER_IP = "192.168.10.101"; 

public static void main(String[] args) throws Exception { 
    ServerSocket serverSocket = new ServerSocket(); 
    serverSocket.bind(null); 

    System.out.println("Started server on port " + serverSocket.getLocalPort() + ", ready for connections"); 

    sendSubscription(serverSocket.getLocalPort()); 

    while (!serverSocket.isClosed()) 
     handle(serverSocket.accept()); 
} 

private static void sendSubscription(int port) throws Exception { 
    Socket socket = new Socket(PLAYER_IP, 1400); 
    PrintWriter out = new PrintWriter(socket.getOutputStream()); 

    out.print("SUBSCRIBE /MediaRenderer/AVTransport/Event HTTP/1.1\r\n" 
      + "HOST: " + PLAYER_IP + ":1400\r\n" 
      + "USER-AGENT: MacOSX/10.12.4 UPnP/1.0 MyApp/0.1\r\n" 
      + "CALLBACK: <http://" + InetAddress.getLocalHost().getHostAddress() + ":" + port + "/dev>\r\n" 
      + "NT: upnp:event\r\n" 
      + "TIMEOUT: Second-3600\r\n" 
      + "\r\n"); 
    out.flush(); 

    BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
    String line; 
    while ((line = in.readLine()) != null) 
     System.out.println(line); 
} 

private static void handle(final Socket clientSocket) { 
    new Thread(new Runnable() { 
     public void run() { 
      System.out.println(); 
      System.out.println("Request incoming " + new Date()); 
      try { 
       BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); 
       String line; 
       while ((line = in.readLine()) != null) { 
        System.out.println(line); 
        if (line.contains("TransportState")) 
         System.out.println("TransportState: " + line.substring(line.indexOf("TransportState") + 25)); 
       } 
      } 
      catch (IOException e) {} 

      try { 
       PrintWriter out = new PrintWriter(clientSocket.getOutputStream()); 
       out.print("HTTP/1.1 200 OK\r\n" 
         + "Server: MacOSX/10.12.4 UPnP/1.0 MyApp/0.1\r\n" 
         + "Connection: close\r\n" 
         + "\r\n"); 
       out.flush(); 
      } 
      catch (IOException e) {} 
     } 
    }).start(); 
} 

它發送訂閱請求,然後不斷地讀取通知。您可能會注意到我沒有使用任何庫,但是我已經因爲偏執狂而取消了這些庫,直到我可以使用這個基本用例來運行。

結果是,當我用我的手機播放/停止軌道或廣播電臺時,事件並不總是到達,當他們這樣做時,他們通常很晚。這種行爲對我的應用程序而言並不一致,因此我認爲我可以排除我的網絡。我已經對我的應用程序和CLing之間的區別進行了分析,訂閱信息幾乎完全相同(我甚至嘗試了CLing發送的確切消息)。兩個應用程序都運行在同一臺PC上,都在同一個JVM上。

根據UPnP規範,媒體渲染器在訂閱後立即發送通知,該通知始終確實到達,並且我看不到任何意外的延遲。

這對我來說很奇怪,而且我很遺憾接下來我可以嘗試。我會永遠感謝任何一個瞭解這個問題的原因的人!

+0

通知是否在預期的時間發送?如在哪個設備中發生延遲? – jku

+0

在運行我的應用程序的同一臺PC上使用Wireshark,我可以看到通知遲到。他們基本上是由我的應用程序立即處理。我嘗試了兩種不同的路由器,看看是否有所作爲,但延遲是相同的。 – delucasvb

回答

1

問題在於某些HTTP服務器實現在某些情況下未發送HTTP響應代碼。媒體渲染器在收到HTTP 200響應之前不會發送下一個事件。對於Java 1.4來說,一個好的,輕量級的HTTP服務器似乎很難找到。