正在中断Java DataInputStream readFully()



我有一个Java小程序,可以从服务器流式传输视频(MJPEG)。我用C#(Windows服务)编写了一个代理服务器,用于放置小程序和多个视频服务器之间。HTML/CSS/Js前端与Java小程序一起使用。除了一件事之外,所有功能都很好(终于!!)。

视频服务器允许您通过REST接口播放录制的视频。剪辑完成后,服务器会打开连接,以防您想向其发送倒带或查找等命令。剪辑在小程序中一直播放到最后。如果你试图启动一个新的剪辑(这需要从Javscript向小程序发送一个命令),浏览器就会冻结。但是,使用相同连接的后续命令会起作用,例如播放、暂停和查找。如果我停止windows服务,浏览器将再次响应。

这就是我假设正在发生的情况:剪辑结束(或暂停);不再发送数据,但连接仍然处于活动状态。小程序正在代理服务器上等待下一帧,但代理服务器正在视频服务器上等待不会再发送任何数据的下一帧。

这是while循环中读取每帧的代码

byte[] img = new byte[mContentLength];
inputStream.skipBytes(headerLen);
inputStream.readFully(img);

我需要以某种方式中断这个代码。

当在HTML前端选择了一个新的视频剪辑时,我们会通知小程序,它会调用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.消息,也没有捕捉到一般的Exception。当我停止Windows服务时,我终于收到了closed.消息,所以看起来inputStream.close();正在阻塞。

所以我想我的问题是,我该如何阻止阻塞?readFully(img)呼叫阻塞了吗?还是断开连接功能(正如我得到的控制台输出所建议的那样)?

编辑:只是为了澄清,我编写了Java小程序、HTML、CSS、Javascript和C#代理服务器,所以我可以访问所有这些代码。我唯一不能修改的代码是视频服务器上的REST接口。

edit2:我本想为这篇文章赚大钱https://stackoverflow.com/questions/12219758/proxy-design-pattern

通常,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);

此代码从InputStream创建一个Channel,并使用Channel读取数据。ReadableByteChannel.read(ByteBuffer)函数的JavaDoc表示,中断包含对inChannel.read(buf)调用的线程将停止读取。

你必须修改这个代码,我刚刚把它从脑子里想出来了。祝你好运

我终于找到了答案:

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,这是一种方法,并且没有输出流,但尝试关闭输出流会引发异常,出于某种原因,这一切都成功了。

相关内容

  • 没有找到相关文章

最新更新