WebSocket

WebSocket 简介:WebSocket 协议支持客户端之间的双向通信,用于此模型是常用的基于源的安全模型通过网络浏览器。该协议包括一个开放握手,然后是基本的消息框架,通过 TCP 分层的目标,这项技术是为基于浏览器的机制提供的,需要与服务器进行双向通信的应用程序不依赖于打开多个 HTTP 连接(例如,使用 XMLHttpRequest 或 iframe 和长轮询)。

上述 WebSocket 的简介来源于 RFC6455 中对 WebSocket 的定义,通过上述简介可知,WebSocket 的出现就是要为了实现一个双向的通信协议,用以抛弃基于 HTTP 轮训而实现的实时通信的效果;当然 WebSocket 协议后续也做了很多优化,包括简化 http 的握手认证,以及多路复用等特性,详情也可以查看 RFC 中关于 WebSocket 最新的编码记载。

2



JSR-356

了解 RFC 以及对应的 WebSocket 协议说明外,此时可以查看下上述截图的第三列“应用开发”,其中应用开发这一列所提到,Tomcat 实现了 JSR-356 所定义的 Java WebSocket 1.1API,也就是说,当前 Tomcat 所实现的 WebSocket 的具体代码实现,是基于 JSR-356 所定义的 JavaWebSocket API 的具体实现。

那么 JSR 是什么?如果说 RFC 是 Internet 上所有被提案且标准化协议的一个说明,那么 JSR 则是 Java 的规范提案;此处来一个百度百科的具体说明,如下:JSR 是 Java Specification Requests 的缩写,意思是 Java 规范提案。是指向 JCP(Java Community Process)提出新增一个标准化技术规范的正式请求。任何人都可以提交 JSR,以向 Java 平台增添新的 API 和服务。JSR 已成为 Java 界的一个重要标准。

Java 有自己的专家组和规范审核组,新增的标准化技术提案和实现则需要进行严格的审核后,便将会作为 Java 的新规范而存在,那么看到这里,应该便是已经清楚了当前 WebSocket 在 Java 中的整体应用说明,各容器 Tomcat 以及 Jetty,或者 WebLoginc 等等,只要是作为 Java 的容器而存在的项目,则在具体实现 WebSocket 这个协议的技术时,都必须遵守且依赖于 Java 自身的 WebSocket 接口和规范,以此来对接 Java 的上层应用实现逻辑;

3



SpringWebSocket, Tomcat WebSocket, Jetty WebSocket, Java-WebSocket.jar 的区别

Tomcat 和 Jetty 本身作为 J2EE 的容器而存在,所以 Tomcat 以及 Jetty 中对于 Websocket 协议的支持,都是基于 Java 自身所定义的接口进行的支持,各容器对 WebSocket 的具体实现方式不同,但常用的 WebSocket 接口,如@ServerPoint(定义一个 WebSocket 接口)等这样的应用层规范,由于是 Java 自身已经定义的接口规范,所以在无需了解具体的容器实现时,只需要关注 Java 自身对于 WebSocket 的实现即可。

当然在具体使用时,需要确认当前容器的版本是否支持 WebSocket 以及是否引入的有对应 WebSocket jar 等,毕竟容器才是对外 socket 协议的具体实现交互类,由于 Tomcat 以及 Jetty 本身的 lib 下是存在对应的 WebSocket 具体的实现 jar 的,所以项目中进行引用的时候,需要设置为非 runtime 运行时使用的 jar,或者直接将对应的容器 lib 直接引入到项目的 librares 中即可。

3.1



Java-WebSocket.jar 具体是做什么?

因为 Java-WebSocket.jar 是 github 上关于 Java websocket 的项目 start 数量最多的一个项目,所以,初次使用或者不熟悉 Java WebSocket 的同学,一般都会直接按照 Java-WebSocket 的实例 Demo 进行 socket 协议的效果验证,结果在具体的 J2EE web 开发中,却会发现一些莫名的问题,比如:虽然我引用了 Java-WebSocket.jar 但最终服务跑起来后,感觉和他并没有神马关系;反而会出现很多 Tomcat 容器不兼容等的容器异常;那么此时则必须了解下,对应的 Java-WebSocket 是做什么的了。

Java-WebSocket 是 github 上一个开源大神写的关于 Java 实现 WebSocket 的一个开源组件,使用它可以做到 Java 中使用 WebSocket 协议,但是!具体的 J2EE 项目中,Tomcat 中所实现的 WebSocket 协议的具体实现,则跟当前的 Java-WebSocket.jar 没有一毛钱关系,换句话说,如果你肯定是基于容器去启动服务的情况下,那么要 Java-webSocket.jar 还是不要这个 Jar 问题不大,因为 Tomcat 容器已经帮你实现了一套 WebSocket 的具体实现了。

但是如果你的服务不是基于 jetty,Tomcat 等容器去启动的话,那么你还想实现 WebSocket 效果,此时的 Java-WebSocket.jar 则是最佳的选择,因为它可以帮你实现 Main 函数启动时定义 WebSocket 端口等一系列事情,注意:Java-WebSocket.jar 对 socket 协议的具体实现,当然也是基于 Java 自身的 WebSocket API 规范来实现的了。

3.2



Spring-WebSocket 是做什么?

既然容器已经帮我们实现了关于 WebSocket 协议的具体实现,那么为什么我还要引入 Spring-WebSocket?我要它做什么?yes,是的,如果你只是单纯的使用 Tomcat 所实现的 WebSocket 时,直接使用@ServerPoint 定义 WebSocket 接口,然后直接使用,当然是没有问题的撒,但是!如果你的项目是基于 Spring 做的开发,比如你引入了 SpringMVC,还引入了 SpringSecurity,那么问你个问题,既然 Spring 已经帮你管理了 Controller 控制层的访问(基于请求拦截),也帮你做了 SpringSecurity 安全请求认证。

为什么你定义一个 WebSocket 接口,Spring 就会直接帮你映射到这个 WebSocket 的控制器上吗?答案是:当然不会,因为 SpringMVC 默认是做基于 Http 的拦截的,如果你想使用 WebSocket 协议,那么你只需要引入 Spring-WebSocket 的 jar 包集就行,它会帮你查找被@ServerPoint 所定义的 socket 接口类,然后将该类定义为 Socket 的实现类,当然具体的 Socket 协议的规范实现,还是容器帮你进行实现。

除此之外,既然 Socket 接口也是归属于 Spring 管理的,那么针对 Socket 协议,Spring-Socket 也帮你实现了一整套的安全规范,可以设置拦截,是否允许非指定的域名访问,等一系列效果;(建议深度使用 Spring 的项目可以引入 Spring-Socket 做一整套的控制,因为 Spring Socket 的确帮你实现了很多一整套的安全认证的功能,容器只是基于 WebSocket 的具体实现罢了,所以,各自分工不同,各个角色所做的事情,使用 socket 时,此处需要牢记,只有明白了各个角色所做的解耦合的事情后,出现异常问题,才更加方便和有思绪的进行排查。