簡體   English   中英

中斷Java DataInputStream readFully()

[英]Interrupting Java DataInputStream readFully()

我有一個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:我打算為這篇文章做出賞賜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,這是一種方式而且沒有輸出流,嘗試關閉輸出流引發了異常,並且出於某種原因使其全部工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM