未及时收到或收到的UPnP事件

时间:2017-05-05 15:22:28

标签: java upnp

我一直致力于简单的UPnP客户端实施,但我在接收事件方面遇到了麻烦。为了尝试查找我发送的消息中的错误,我使用CLing测试了我的用例(这是一个很棒的库,但它依赖于Java 1.5,而我只能访问1.4),它完美地工作,但我可以&# 39;在其消息和我的消息之间找到任何有意义的差异。

我正在订阅/ 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之间的区别和订阅消息几乎相同(我甚至尝试过CLing发送的确切消息)。两个应用程序都在同一台PC上运行,两者都在同一个JVM上。

根据UPnP规范,媒体渲染器会在订阅后立即发送通知,该通知始终会到达,并且我看不到任何意外延迟。

这对我来说很奇怪,而我却失去了接下来可以尝试的东西。我会永远感激任何一个知道这个问题的原因是什么的人!

1 个答案:

答案 0 :(得分:2)

问题在于HTTP服务器实现在某些情况下没有发送HTTP响应代码。媒体渲染器在收到HTTP 200响应之前不会发送下一个事件。对于Java 1.4来说似乎是一个好的,轻量级的HTTP服务器很难找到。