Tomcat如何实现WebSocket

简介: WebSocket协议属于HTML5标准,越来越多浏览器已经原生支持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

此时如果服务器端支持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=

完成如上握手后,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();               
            }
        }
    }
}

这个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协议的支持。

这里写图片描述

点击订购作者《Tomcat内核设计剖析》

博主的书

目录
相关文章
|
1月前
|
网络协议 Java 应用服务中间件
Tomcat中的WebSocket是如何实现的?
【10月更文挑战第7天】本文介绍了WebSocket在Tomcat中的实现,包括其全双工通信、单个TCP连接、协议升级和事件驱动的特点。通过Spring Boot项目整合WebSocket,展示了如何配置依赖、创建WebSocket处理类和配置类。详细解析了WebSocket的原理,包括ServerEndpointExporter的注册过程和请求处理流程。总结了WebSocket与HTTP请求处理的区别,并提供了进一步学习的资源。
Tomcat中的WebSocket是如何实现的?
|
5月前
|
Web App开发 移动开发 Java
基于tomcat运行HTML5 WebSocket echo例子
基于tomcat运行HTML5 WebSocket echo例子
46 2
|
Web App开发 Java 应用服务中间件
Java后端WebSocket的Tomcat实现
文章摘要随着互联网的发展,传统的HTTP协议已经很难满足Web应用日益复杂的需求了。近年来,随着HTML5的诞生,WebSocket协议被提出,它实现了浏览器与服务器的全双工通信,扩展了浏览器与服务端的通信功能,使服务端也能主动向客户端发送数据。
1820 0
|
Web App开发 移动开发 应用服务中间件
基于tomcat运行HTML5 WebSocket echo例子
一:概述 作为HTML5新特性之一的WebSocket组件,在实时性有一定要求的WEB应用开发中还是有一定用武之地,高版本的IE、Chrome、FF浏览器都支持Websocket,标准的Websocket通信是基于RFC6455实现服务器端与客户端握手与消息接发的。
1215 0
|
应用服务中间件 网络协议
Tomcat 7的WebSocket实现(下)
版权声明:本文为博主chszs的原创文章,未经博主允许不得转载。 https://blog.csdn.net/chszs/article/details/20153123 Tomcat 7的WebSocket实现(下) 作者:chszs,转载需注明。
732 0
|
应用服务中间件 Apache 容器
Tomcat 7的WebSocket实现(上)
Tomcat 7的WebSocket实现(上) 本文覆盖了以下内容: 1)Web通信的演进 2)WebSocket 3)WebSocket在Apache Tomcat 7的实现 4)怎样用Jaggery开发WebSocket特性 Tomcat 7中引入了WebSocket实现。
1317 0
|
应用服务中间件
Tomcat 7的WebSocket实现(下)
Tomcat 7的WebSocket实现(下) 下面来看一下WebSocket的交互情况: 1)头部“Connection:upgrade” 2)响应包含关键状态码101 3)表明协议交换已经证明 在客户端和服务器之间的握手协议完成后,抛弃请求/响应通信,彼此开始独立的互发消息。
995 0