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如何实现WebSocket的更多相关文章

  1. tomcat jdk servlet websocket版本对应关系

    最近在考虑公司主要基础三方库版本统一和升级的问题,特看了下tomcat jdk servlet websocket版本的对应关系,如下:

  2. 使用tomcat方式实现websocket即时通讯服务端讲解

    使用tomcat方式实现websocket即时通讯服务端讲解 第一种方案:使用Tomcat的方式实现 tomcat版本要求:tomcat7.0+.需要支持Javaee7 导入javeee-api的ja ...

  3. springboot深入学习(四)-----tomcat配置、websocket

    一.更改servlet服务器 springboot中默认可以集成多种servlet容器,当引入如下依赖时: springboot默认以tomcat作为项目的servlet容器,如果用户想要替换tomc ...

  4. Java后端WebSocket的Tomcat实现 html5 WebSocket 实时聊天

    WebSocket协议被提出,它实现了浏览器与服务器的全双工通信,扩展了浏览器与服务端的通信功能,使服务端也能主动向客户端发送数据.Tomcat7.0.47上才能运行. 需要添加Tomcat里lib目 ...

  5. tomcat支持的websocket服务

    首发:个人博客 在tomcat7之后的版本,写个websocket服务程序非常容易——如以下代码所示,当客户端建立了一个连接并发送了一些什么内容到服务器,服务器将每隔两秒返回一个字符串“world”. ...

  6. Springboot使用外置tomcat的同时使用websocket通信遇到的坑

    随意门:https://blog.csdn.net/qq_43323720/article/details/99660430 另外,使用了nginx的话,需要注意开放websocket支持 serve ...

  7. html5利用websocket完成的推送功能(tomcat)

    html5利用websocket完成的推送功能(tomcat) 利用websocket和java完成的消息推送功能,服务器用的是tomcat7.0.42,一些东西是自己琢磨的,也不知道恰不恰当,不恰当 ...

  8. websocket之三:Tomcat的WebSocket实现

    Tomcat自7.0.5版本开始支持WebSocket,并且实现了Java WebSocket规范(JSR356 ),而在7.0.5版本之前(7.0.2版本之后)则采用自定义API,即WebSocke ...

  9. 75篇关于Tomcat源码和机制的文章

    75篇关于Tomcat源码和机制的文章 标签: tomcat源码机制 2016-12-30 16:00 10083人阅读 评论(1) 收藏 举报  分类: tomcat内核(82)  版权声明:本文为 ...

随机推荐

  1. 两个css之间的切换

    需求: 头部两个按钮 两种样式之间的切换 解决办法: 结合JQ  三目运算 来处理 第一步: 把需要切换的样式设置为样式里背景,这样做的目的为了避免 js里出现过多 css代码 二来这样会显得更加的清 ...

  2. Ubantu16.04系统优化

    系统清理篇 系统更新 安装完系统之后,需要更新一些补丁.Ctrl+Alt+T调出终端,执行一下代码: sudo apt-get update sudo apt-get upgrade 卸载libreO ...

  3. python数据挖掘_Json结构分析

    json是一种轻量级的数据交换格式,也可以说是一种配置文件的格式 这种格式的文件是我们在数据处理经常会遇到的 python提供内置的模块json,只需要在使用前导入即可 你可以通过帮助函数查看json ...

  4. svg从入门到装逼(一)

    svg文件是基于xml的矢量图,而canvas是基于html和js的位图.关于两者的比较,在粗就不赘述了. 1.  首先来上一个svg的基本结构: <?xml version="1.0 ...

  5. [ZJOI2008]泡泡堂

    题目描述 第XXXX届NOI期间,为了加强各省选手之间的交流,组委会决定组织一场省际电子竞技大赛,每一个省的代表队由n名选手组成,比赛的项目是老少咸宜的网络游戏泡泡堂.每一场比赛前,对阵双方的教练向组 ...

  6. 51 nod 1456 小K的技术(强连通 + 并查集)

    1456 小K的技术 题目来源: CodeForces 基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题   苏塞克王国是世界上创新技术的领先国家,在王国中有n个城市 ...

  7. 【Luogu P2709 小B的询问】莫队

    题目描述 小B有一个序列,包含N个1~K之间的整数.他一共有M个询问,每个询问给定一个区间[L..R],求Sigma(c(i)^2)的值,其中i的值从1到K,其中c(i)表示数字i在[L..R]中的重 ...

  8. NOIP2014-7-7模拟赛

    1.无线通讯网(wireless.pas/cpp/c) [题目描述] 国防部计划用无线网络连接若干个边防哨所.2种不同的通讯技术用来搭建无线网络:每个边防哨所都要配备无线电收发器:有一些哨所还可以增配 ...

  9. 2015 多校联赛 ——HDU5373(模拟)

    Problem Description In this problem, we should solve an interesting game. At first, we have an integ ...

  10. poj 3335 Rotating Scoreboard(半平面交)

    Rotating Scoreboard Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 6420   Accepted: 25 ...