我有一个Java applet,它从服务器流式传输视频(MJPEG)。我用C#(Windows服务)编写了一个代理服务器,放在applet和多个视频服务器之间。 HTML / CSS / Js前端与Java applet一起使用。所有功能都可以正常工作(最后!!!),除了一件事。
视频服务器允许您通过REST界面播放录制的视频。剪辑完成后,服务器将打开连接,以防您想要发送倒带或搜索等命令。该剪辑在小程序中正常播放,直到结束。如果您尝试启动一个新剪辑(需要从Javscript向applet发送命令),浏览器会冻结。但是,后续使用相同连接的命令会起作用,例如播放,暂停和搜索。如果我停止Windows服务,浏览器会再次响应。
这就是我假设正在发生的事情:剪辑结束(或暂停);不再发送数据但连接仍处于活动状态。 applet正在等待下一帧的代理,但是代理正在视频服务器上等待下一帧,这不会再发送任何数据。
这是读取每个帧的while循环中的代码
byte[] img = new byte[mContentLength];
inputStream.skipBytes(headerLen);
inputStream.readFully(img);
我需要以某种方式中断此代码。
当在HTML前端中选择新的视频片段时,我们会通知applet,它在CameraStream类上调用disconnect()。这就是这个功能:
// DataInputStream inputStream
// HttpURLConnection conn
public void disconnect() {
System.out.println("disconnect called.");
if(running) {
running = false;
try {
// close the socket
if(inputStream != null) {
inputStream.close();
}
if(conn != null) {
conn.disconnect();
}
inputStream = null;
System.out.println("closed.");
} catch(Exception ignored) {
System.out.println("exc:" + ignored.getMessage());
main.reportErrorFromThrowable(ignored);
}
}
}
为了测试这个,我让一个快速剪辑播放并运行到最后。然后我选择一个新剪辑。在我的Java控制台中,我得到了输出disconnect called.
,但是我没有得到后续的closed.
消息,也没有捕到该通用异常。当我停止Windows服务时,我终于收到了closed.
消息,因此看起来inputStream.close();
正在阻止。
所以我想我的问题是如何阻止阻止? readFully(img)
来电是否被阻止?或者它是断开连接功能(我得到的控制台输出建议)?
编辑为了澄清,我编写了Java applet,HTML,CSS,Javascript和C#代理服务器,因此我可以访问所有代码。我无法修改的唯一代码是视频服务器上的REST接口。
edit2:我打算为此帖{4}付出赏金
答案 0 :(得分:0)
通常,Java I / O方法会阻塞。最好的解决方案似乎是创建另一个线程来读取数据和使用NIO缓冲区。基于NIO的读取示例(警告:未经测试!):
// get the InputStream from somewhere (a queue possibly)
ReadableByteChannel inChannel = Channels.newChannel(inputStream);
ByteBuffer buf = ByteBuffer.allocate(mContentLength + headerLen);
inChannel.read(buf);
byte[] img = new byte[mContentLength];
inChannel.get(img, headerLen, mContentLength);
此代码从Channel
创建InputStream
并使用Channel
来读取数据。 ReadableByteChannel.read(ByteBuffer)
函数的JavaDoc表示,中断包含对inChannel.read(buf)
的调用的线程将停止读取。
你必须调整这段代码,我只是把它拉出来。祝你好运!
答案 1 :(得分:0)
我终于找到了答案:
public void disconnect() {
if(running) {
running = false;
try {
try{
// had to add this
conn.getOutputStream().close();
}
catch(Exception exc){
}
// close the socket
if(inputStream != null) {
inputStream.close();
}
if(conn != null) {
conn.disconnect();
}
inputStream = null;
} catch(Exception ignored) {
main.reportErrorFromThrowable(ignored);
}
}
}
即使我正在使用HttpUrlConnection,这是一种方式而且没有输出流,尝试关闭输出流引发了异常,并且出于某种原因使它全部工作。