![](/img/trans.png)
[英]jetty 9, websockets and closing websocket connection on server side
[英]Websocket(Jetty) : How to handle the binary data on server side which is coming in chunks
我需要設置一個可以接收客戶端發送的音頻數據的 websocket 服務器。 為此,我正在使用 Jetty。
我的處理程序代碼:
{
@OnWebSocketClose
public void onClose(int statusCode, String reason) {
}
@OnWebSocketError
public void onError(Throwable t) {
}
@OnWebSocketConnect
public void onConnect(Session session) {
}
@OnWebSocketMessage
public void onMessage(String message) {
}
@OnWebSocketMessage
public void onMessage(bytes [] b) {
}
@OnWebSocketMessage
public void inputStream(InputStream is) {
}
}
由於音頻文件非常大,客戶端將它們分塊發送。 現在對於每個塊,都會調用onMessage(bytes [] b) {}
方法。
在服務器端,我需要添加這些塊並處理音頻。 我怎樣才能做到這一點?
另外onMessage(bytes [] b) {}
和onMessage(InputStream is) {}
方法有什么區別?
根據onMessage
javadoc , onMessage(byte[] b)
和onMessage(InputStream is)
都將收到整個消息:
如果該方法正在處理二進制消息:
- byte[] 或 ByteBuffer 接收整個消息
- InputStream 以阻塞流的形式接收整個消息
因此,如果您使用這些方法之一,Jetty 將自動重新組合塊並將整個消息傳遞給您的方法(作為byte[]
數組或InputStream
)。
二進制消息的最大大小,可以這樣接收,用setMaxBinaryMessageSize設置
另請注意,您可能一次只能在 Handler 類中定義以下方法之一:
每個 websocket 端點對於每種原生 websocket 消息格式可能只有一種消息處理方法:文本、二進制和 pong。
如果你想處理數據,你應該使用下面的方法簽名:
@OnMessage
public void processUpload(byte[] b, boolean last, Session session) {
// process partial data here, which check on last to see if these is more on the way
}
並手動緩沖您的數據(在內存或磁盤文件等中)
反過來,客戶端應該使用sendPartialBytes方法之一, 逐塊發送數據。
如果您觀察到的是為每個數據塊調用的“完整消息”方法(即onMessage(byte[] b
),由客戶端發送,則表明客戶端沒有利用協議功能來發送分塊消息,而是拆分輸入數據,然后將其部分作為獨立的WS 消息發送,有效地創建了自己的應用程序級協議,用於以塊的形式傳輸數據。
在這種情況下,您必須更新客戶端(如果這是一個選項),使其使用常規 WS 協議功能,或者實現客戶端正在使用的相同“應用程序級協議”。
下面是一個超級簡單的端點示例,它將緩沖輸入數據,直到 WS 套接字關閉(這意味着客戶端將在發送所有塊后關閉連接)。
@ServerEndpoint("/data")
public static class Handler {
private ByteArrayOutputStream buffer = new ByteArrayOutputStream();
@OnMessage
public void onMessage(byte[] message) throws IOException {
buffer.write(message);
}
@OnClose
public void onClose(Session session) throws IOException {
System.out.println(
buffer.toByteArray().length
);
}
}
此實現還意味着使用默認的ServerEndpointConfig.Configurator ,因此每個連接只有一個 Endpoint 實例(如此處所述)。
更復雜的實現可能希望重用套接字來發送多個文件,並指定一種機制來表示每次傳輸的開始和結束(例如,使用特殊格式的消息),但這完全取決於您的客戶端是如何實現的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.