我一直致力于简单的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规范,媒体渲染器会在订阅后立即发送通知,该通知始终会到达,并且我看不到任何意外延迟。
这对我来说很奇怪,而我却失去了接下来可以尝试的东西。我会永远感激任何一个知道这个问题的原因是什么的人!
答案 0 :(得分:2)
问题在于HTTP服务器实现在某些情况下没有发送HTTP响应代码。媒体渲染器在收到HTTP 200响应之前不会发送下一个事件。对于Java 1.4来说似乎是一个好的,轻量级的HTTP服务器很难找到。