UPnP events not received or received

I'm working on a simple UPnP client implementation, but I'm having trouble getting events. To try and find errors in the posts I am posting, I tested my use case with CLing (this is an awesome library, but it depends on Java 1.5 and I only have access to 1.4) which works great, but I can't find any significant difference between his messages and mine.

I am subscribing to events / MediaRenderer / AVTransport / Event, testing if I can get the latest TransportState.

Here's my test code:

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();
}

      

It sends a subscription request and then continuously reads notifications. You may have noticed that I am not using any libraries for anything, but I have removed them out of paranoia until I can use this basic use case.

As a result, when I use my phone to play / stop a track or radio station, for example, events don't always arrive, and when they do, they are often very late. This behavior is compatible for my application, not CLing, so I concluded that I could exclude my network. I have Wiresharked the difference between my app and CLing, and the subscription messages are almost identical (I even tried the exact message CLing sends). Both applications run on the same PC as on the same JVM.

As per the UPnP spec, the media renderer sends a notification immediately after subscribing, which always arrives and I don't see any unexpected delay there.

This is very strange for me, and I am at a loss what I can try next. I would be eternally grateful to anyone with an idea of ​​what might be causing this question!

+3


source to share


1 answer


The problem was the implementation of the HTTP server, which in some cases did not send HTTP response codes. The media renderer did not dispatch the next event before it received an HTTP 200 response. Sounds like a good, lightweight HTTP server for Java 1.4 is a tricky find.



+1


source







All Articles