Websocket java api (jsr 356) study notes

websocket 下一代即时通讯的技术前沿.

java 方面的规范jsr 356 已经正式通过,最近着重研究此项技术,尝试在项目中使用websocket技术.

(一)先看下 Java Websocket API

以下是简要的api class diagram



解释一下规范中的基本名词:

Endpoint: 端点, websocke一端的连接点,是一个java组件.

 

Connection: 连接, 保持websocket 两端间的连接对象.

 

Session: 一次回话, websocket 建立链接后建立的回话.

 

ClentEndPoint/ ServerEndPoint : websocket客户端/服务端.

客户端只能连接一个EndPoint.服务端可以链接多个EndPoint.当链接建立后,客户端及服务端均可以主动发送/接受消息,此时,则无客户端及服务器端的概念.


(二) Websocket 服务建立此处只记录在web server 环境下

(1)    Websocket 在web server启动时,扫描web-inf/classes及 web-inf/lib下的类,扫描到带有websocket 注解( @serverEndpoint )及Endpoint的子类以及 ServerApplicationConfig子类.ServerApplicationConfig类是为了创建Endpoint子类在系统中的配置. 传入扫描到的Endpoint类, 创建ServerEndPointConfig.class 配置实例,  返回 包含serverEndPoint 的Set集. 此处可创建 而serverEndPoint可 endPoint的URI,timeout等配置,serverEndpoint中包含的Configurator可以预处理webSocket握手handshake,添加特殊的处理过程.(用modifyHandshake实现,其还包含其他有用方法).

(2)    当没有扫描到ServerAppliacationConfig子类的时候,则默认强制为扫描到的annotation类生成ServerEndPointConfig实例,也就是说可以为注解类生成websocket服务配置,及注解类是很容易部署的.


Websocket deploy sequence diagram



ServerApplicationConfig Example:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. public class ExamplesConfig implements ServerApplicationConfig {  
  2.     @Override  
  3.     public Set<ServerEndpointConfig> getEndpointConfigs(  
  4.             Set<Class<? extends Endpoint>> scanned) {  
  5.         Set<ServerEndpointConfig> result = new HashSet<ServerEndpointConfig>();  
  6.         if (scanned.contains(EchoEndpoint.class)) {  
  7.             result.add(ServerEndpointConfig.Builder.create( EchoEndpoint.class,  
  8.                     "/websocket/echoProgrammatic").build());  
  9.         } return result;  
  10.     }  
  11.     @Override  
  12.     public Set<Class<?>> getAnnotatedEndpointClasses(Set<Class<?>> scanned) {  
  13.         // Deploy all WebSocket endpoints defined by annotations in the examples  
  14.         // web application. Filter out all others to avoid issues when running  
  15.         // tests on Gump  
  16.         Set<Class<?>> results = new HashSet<>();  
  17.         for (Class<?> clazz : scanned) {  
  18.             ServerEndpoint serverEndpoint =clazz.getAnnotation(ServerEndpoint.class);  
  19.             ClientEndpoint clientEndpoint = clazz.getAnnotation(ClientEndpoint.class);  
  20.             if(serverEndpoint != null || clientEndpoint != null){  
  21.                 results.add(clazz);  
  22.             }  
  23.         } return results;  
  24.     }  
  25. }  


(3)    Bulid connection between client and server.

1.      握手客服端发送http升级协议的握手请求,请求服务端建立websocket链接.

此时可以改写服务端的ServerEndpointConfig.Configurator类的modifyHandshake方法,增加握手处理.

 

2.      服务端接收到握手请求后,判断是否与该客户端建立链接,若同意,则返回同意升级协议,建立websocket链接的响应.否则发送不与升级的响应

3.      客户端收到服务器响应,判断是否升级协议,若升级,则发送建立websocket connection,服务端根据请求url调用响应的Endpoint的onopen方法.

4.      服务端在onopen方法里初始化本次链接中的session信息,包括初始化MessagerHandler,(若是注解,则不需要,注解调用OnMessager注解的方法)

每一种消息类型,服务端只能为session注册唯一的一种类型的MessageHandler.如String类型的数据,只能注册一种处理String类型的MessagerHandler处理.而messagerHandler有两种类型,一种Partial,一种为Whole,

顾名思义,Partial信息,适用于部分消息,当onmessager的last(是否为本次消息的最后一部分消息)参数为true时,与Whole相同;

Whole适用于全部消息.

此处仍有疑问,这个PartialWhole的适用场景是什么呢?是否可以为同一个session注册消息类型相同但处理类型分别是PartialWhole的消息处理类呢.

tomcatexample, whole用做Endpoint的私有属性,PartialSession的局部变量.这又有何分别呢?

 

 

当发送响应时,调用session的getRemoteEndPoint方法,RemoteEndPoint也有两种.一种Basic及Async.

Basic类型发送消息为block-io, Async 则为NIO,及一个同步,一个是异步发送.

 

5.      客服端发送信息,服务器端调用响应的Endpoint的onMessage注解方法或MessagerHandler处理.根据消息类型进行判断具体调用那个方法.

OnMessage有个参数Msg, 可以覆盖该方法,msg的类型不同.但同一种类型只能覆盖一次.如果没有注册,则表示不处理此类型的消息.

 

6.      保持链接,发送客户端发送ping信息,服务端响应pong message.

7.      当发生服务端发送错误/运行异常时,调用Endpoint 的onError或@OnError注解方法

 

8.     关闭连接必须调用 onclose方法.以通知客户端关闭链接.

Websocket message exchange diagram:



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值