2017-05-05 2 views
3

간단한 UPnP 클라이언트 구현을 위해 노력했지만 이벤트를받는 데 문제가 있습니다. 내가 보내고있는 메시지의 결함을 찾으려면 CLing (멋진 라이브러리이지만 Java 1.5에 달려 있지만 1.4에 액세스 할 수는 있지만)에서 완벽하게 작동하는 사용 사례를 테스트했지만 찾지 못했다. 그것의 메시지와 나의 의미심장 한 차이.UPnP 이벤트가 늦게 수신되거나 수신되지 않았습니다.

/MediaRenderer/AVTransport/Event 이벤트에 가입하여 최신 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 및 구독 메시지의 차이점을 Wiresharked 거의 (나는 심지어 정확한 메시지를 CLing 보내려고했습니다) 동일합니다. 두 응용 프로그램은 동일한 JVM에서 동일한 PC에서 실행됩니다.

UPnP 사양에 따라 미디어 렌더러는 구독 후 즉시 알림을 보내고 항상 도착하며 예상치 못한 지연은 없습니다.

이것은 매우 이상한 일이며 다음에 시도 할 수있는 것을 잃어 버렸습니다. 나는이 문제의 원인이 무엇인지에 대해 생각해 본 사람에게 영원히 감사 할 것입니다!

+0

예상되는 시간에 알림을 보내고 있습니까? 에서 어떤 지연이 일어나는가? – jku

+0

내 앱을 실행하는 동일한 PC에서 Wireshark를 사용하면 알림이 늦게 전송되는 것을 볼 수 있습니다. 그들은 기본적으로 내 애플 리케이션에 의해 즉시 처리됩니다. 그 차이가 있는지 확인하기 위해 두 개의 다른 라우터를 시도했지만 지연은 동일합니다. – delucasvb

답변

1

일부 경우 HTTP 응답 코드를 보내지 않은 HTTP 서버 구현 문제가있었습니다. 미디어 렌더러는 HTTP 200 응답을 받기 전에 다음 이벤트를 보내지 않습니다. 자바 1.4를위한 좋은, 가벼운 HTTP 서버는 어려운 발견이다.

관련 문제