我有一个Java applet,它从服务器上流视频(MJPEG)。我用C# (Windows )编写了一个代理服务器,在applet和多个视频服务器之间放置。HTML/CSS/Js前端与Java一起使用。所有功能都正常工作(最后!),除了一件事。
视频服务器允许您通过REST接口播放录制的视频。剪辑完成后,服务器将打开连接,以防您想要向其发送命令,如倒带或查找。剪辑在小程序中播放得很好,直到结束。如果您尝试启动一个新的剪辑(这需要将命令从Javscript发送到applet),浏览器就会结冰。但是,将使用相同连接的后续命令(如play、pause和seek )也会工作。如果我停止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)呼叫阻塞了吗?或者是断开函数(正如我得到的控制台输出所建议的那样)?
编辑:只是为了澄清,我编写了Javascript、HTML、Javascript和C#代理服务器,所以我可以访问所有这些代码。我唯一不能修改的代码是视频服务器上REST接口的代码。
edit2:,我本想为这篇文章做赏金的,https://stackoverflow.com/questions/12219758/proxy-design-pattern
发布于 2012-09-06 22:01:35
我终于想出了答案:
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,这是一种方法,并且没有输出流,但是试图关闭输出流会引发一个异常,并由于某种原因使其全部工作。
发布于 2012-09-03 21:26:00
通常,Java /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读取数据。用于JavaDoc函数的ReadableByteChannel.read(ByteBuffer)表示,中断包含对inChannel.read(buf)的调用的线程将停止读取。
你得修改这段代码,我刚把它从脑子里拔出来。祝好运!
https://stackoverflow.com/questions/12186643
复制相似问题