Tomcat如何實現WebSocket
Tomcat如何實現WebSocket
WebSocket協議屬於HTML5標準,越來越多瀏覽器已經原生支援WebSocket,它能讓客戶端和服務端實現雙向通訊。在客戶端和伺服器端建立一條WebSocket連線後,伺服器端訊息可直接傳送到客戶端,從而打破傳統的請求響應模式,避免了無意義的請求。比如傳統的方式可能會使用AJAX不斷請求伺服器端,而WebSocket則可以直接傳送資料到客戶端且客戶端不必請求。同時,由於有了瀏覽器的原生支援,編寫客戶端應用程式也變得更加便捷且不必依賴第三方外掛。另外,WebSocket協議摒棄了HTTP協議繁瑣的請求頭,而是以資料幀的方式進行傳輸,效率更高。
圖為WebSocket協議通訊的過程,首先客戶端會傳送一個握手包告訴伺服器端我想升級成WebSocket,不知道你伺服器端是否同意,這時如果伺服器端支援WebSocket協議則會返回一個握手包告訴客戶端沒問題,升級已確認。然後就成功建立起了一條WebSocket連線,該連線支援雙向通訊,並且使用WebSocket協議的資料幀格式傳送訊息。
握手過程需要說明下,為了讓WebSocket協議能和現有HTTP協議Web架構互相相容,所以WebSocket協議的握手要基於HTTP協議,比如客戶端會傳送類似如下的HTTP報文到伺服器端請求升級為WebSocket協議,其中包含的Upgrade: websocket就是告訴伺服器端我想升級協議:
GET ws://localhost:8080/hello HTTP/1.1
Origin: http://localhost:8080
Connection: Upgrade
Host: localhost:8080
Sec-WebSocket-Key: uRovscZjNol/umbTt5uKmw==
Upgrade: websocket
Sec-WebSocket-Version: 13
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 1
- 2
- 3
- 4
- 5
- 6
- 7
此時如果伺服器端支援WebSocket協議,則它會傳送一個同意客戶端升級協議的報文,具體報文類似如下,其中Upgrade: websocket就是告訴客戶端我同意你升級協議:
HTTP/1.1 101 WebSocket Protocol Handshake
Date: Fri, 10 Feb 2016 17:38:18 GMT
Connection: Upgrade
Server: Kaazing Gateway
Upgrade: WebSocket
Sec-WebSocket-Accept: rLHCkw/SKsO9GAH/ZSFhBATDKrU=
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
完成如上握手後,HTTP協議連線就被打破,接下去則是開始使用WebSocket協議進行雙方通訊,這條連線還是原來的那條TCP/IP連線,埠也還是原來的80或443。
下面舉一個Tomcat中編寫WebSocket的簡單例子:
public class HelloWebSocketServlet extends WebSocketServlet {
private static List<MessageInbound> socketList = new ArrayList<MessageInbound>();
protected StreamInbound createWebSocketInbound(String subProtocol,HttpServletRequest request){
return new WebSocketMessageInbound();
}
public class WebSocketMessageInbound extends MessageInbound{
protected void onClose(int status){
super.onClose(status);
socketList.remove(this);
}
protected void onOpen(WsOutbound outbound){
super.onOpen(outbound);
socketList.add(this);
}
@Override
protected void onBinaryMessage(ByteBuffer message) throws IOException {
}
@Override
protected void onTextMessage(CharBuffer message) throws IOException {
for(MessageInbound messageInbound : socketList){
CharBuffer buffer = CharBuffer.wrap(message);
WsOutbound outbound = messageInbound.getWsOutbound();
outbound.writeTextMessage(buffer);
outbound.flush();
}
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
這個Servlet必須要繼承WebSocketServlet,接著建立一個繼承MessageInbound的WebSocketMessageInbound類,在該類中填充onClose、onOpen、onBinaryMessage和onTextMessage等方法即可完成各個事件的邏輯,其中onOpen會在一個WebSocket連線建立時被呼叫,onClose會在一個WebSocket關閉時被呼叫,onBinaryMessage則是Binary方式下接收到客戶端資料時被呼叫,onTextMessage則是Text方式下接收到客戶端資料時被呼叫。上面一段程式碼實現了一個廣播的效果。
按照上面的處理邏輯,Tomcat對WebSocket的整合就不會太難了,就是在處理請求時如果遇到WebSocket協議請求則做特殊處理,保持住連線並在適當的時機呼叫WebSocketServlet的MessageInbound的onClose、onOpen、onBinaryMessage和onTextMessage等方法。由於WebSocket一般建議在NIO模式下使用,所以看看NIO模式整合WebSocket協議。
如圖,對於WebSocket的客戶端連線被接收器接收後註冊到NioChannel佇列中,Poller元件不斷輪休是否有NioChannel需要處理,如果有則經過處理管道後進到繼承了WebSocketServlet的Servlet上,WebSocketServlet的doGet方法會處理WebSocket握手,告訴返回客戶端同意升級協議。往後Poller繼續不斷輪休相關NioChannel,一旦發現是使用WebSocket協議的管道則會呼叫MessageInbound的相關方法,完成不同事件的處理,從而實現對WebSocket協議的支援。
- 上一篇logstash處理檔案進度記錄機制
- 下一篇ELK搭建
相關文章
- websocket和http有什麼不同?以及websocket協議如何實現?WebHTTP協議
- 如何在TOMCAT中實現SSO?Tomcat
- 在Rust中如何高效實現WebSocket? - ahmadrosidRustWebROS
- OkHttp實現分析之WebsocketHTTPWeb
- WebSocket 實現原理淺析Web
- websocket web 實現記錄Web
- 如何使用Jmeter實現WebSocket協議的介面測試JMeterWeb協議
- 華納雲:如何實現tomcat自動化部署Tomcat
- websocket學習和群聊實現Web
- angular + express 實現websocket通訊AngularExpressWeb
- SpringBoot 快速實現WebSocketSpring BootWeb
- Flutter websocket 實現訊息推送FlutterWeb
- ngx_lua_websocket server實現WebServer
- 使用Java實現WebSocket通訊JavaWeb
- Websocket:TomCat7 與 TomCat8的區別WebTomcat
- Go使用websocket實現彈幕功能GoWeb
- [譯] Go 實現百萬 WebSocket 連線GoWeb
- Django使用Channels實現WebSocket--下篇DjangoWeb
- Django使用Channels實現WebSocket--上篇DjangoWeb
- WebRTC + WebSocket 實現視訊通話Web
- WebSocket實現前後端通訊Web後端
- Django3使用WebSocket實現WebShellDjangoWebshell
- Django使用channels實現Websocket連線DjangoWeb
- php : tp框架swoole實現websocket,wssPHP框架Web
- gin websocket 簡單分散式實現Web分散式
- NodeJS實現websocket代理機制NodeJSWeb
- Websocketd:以Unix方式實現的WebsocketWeb
- Tomcat程式碼實現Tomcat
- Tomcat實現Web SocketTomcatWeb
- web server apache tomcat11-31-websocketWebServerApacheTomcat
- WebSocket的故事(六)—— Springboot中,實現更靈活的WebSocketWebSpring Boot
- Uniapp 使用 GoEasy 實現 websocket 實時通訊APPGoWeb
- 實現一個websocket伺服器-實踐篇Web伺服器
- 微信小程式實現WebSocket心跳重連微信小程式Web
- STOMP協議——基於Websocket實現協議Web
- 用 Golang 實現百萬級 Websocket 服務GolangWeb
- 基於Websocket的簡易webshell實現Webshell
- websocket技術,實現單聊和群聊Web