首页 > 网站 > 建站经验 > 正文

Tomcat实现WebSocket的方法

2019-11-02 16:36:52
字体:
来源:转载
供稿:网友

 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.1Origin: http://localhost:8080Connection: UpgradeHost: localhost:8080Sec-WebSocket-Key: uRovscZjNol/umbTt5uKmw==Upgrade: websocketSec-WebSocket-Version: 13

此时如果服务器端支持WebSocket协议,则它会发送一个同意客户端升级协议的报文,具体报文类似如下,其中Upgrade: websocket就是告诉客户端我同意你升级协议:

HTTP/1.1 101 WebSocket Protocol HandshakeDate: Fri, 10 Feb 2016 17:38:18 GMTConnection: UpgradeServer: Kaazing GatewayUpgrade: WebSocketSec-WebSocket-Accept: rLHCkw/SKsO9GAH/ZSFhBATDKrU=

完成如上握手后,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);}@Overrideprotected void onBinaryMessage(ByteBuffer message) throws IOException {}@Overrideprotected void onTextMessage(CharBuffer message) throws IOException {for(MessageInbound messageInbound : socketList){CharBuffer buffer = CharBuffer.wrap(message);WsOutbound outbound = messageInbound.getWsOutbound();outbound.writeTextMessage(buffer);outbound.flush(); }}}}

这个Servlet必须要继承WebSocketServlet,接着创建一个继承MessageInbound的WebSocketMessageInbound类,在该类中填充onClose、onOpen、onBinaryMessage和onTextMessage等方法即可完成各个事件的逻辑,其中onOpen会在一个WebSocket连接建立时被调用,onClose会在一个WebSocket关闭时被调用,onBinaryMessage则是Binary方式下接收到客户端数据时被调用,onTextMessage则是Text方式下接收到客户端数据时被调用。上面一段代码实现了一个广播的效果。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表