一步步学WebSocket(1)声明式WebSocket

简介:

本节描述声明式WebSocket编程,可以与后一篇编程式WebSocket作对比学习:

首先上服务端:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@ServerEndpoint ( "/chat" )
public  class  DeclarativeServer {
     @OnOpen  
     public  void  onOpen(Session session) {  
         System.out.println( "Somebody is coming!" );
      }  
   
     @OnClose  
     public  void  onClose() {  
     }  
   
     @OnMessage  
     public  void  onMessage(String message, Session session)  throws  IOException {
       System.out.println(message); 
       session.getBasicRemote().sendText( "it is sickening" );
     }  
   
 
     @OnError  
     public  void  onError(Session session, Throwable error) {  
         error.printStackTrace();  
     }  
}

通过ServerEndpoint注解将一个POJO声明为WebSocket Server端点(Endpoint和web service的概念endpoint类同)。

ServerEndpoint注解声明如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@Retention (RetentionPolicy.RUNTIME)
@Target (ElementType.TYPE)
public  @interface  ServerEndpoint {
 
     /**
      * URI or URI-template that the annotated class should be mapped to.
      * @return The URI or URI-template that the annotated class should be mapped
      *         to.
      */
     String value();
 
     String[] subprotocols()  default  {};
 
     Class<?  extends  Decoder>[] decoders()  default  {};
 
     Class<?  extends  Encoder>[] encoders()  default  {};
 
     public  Class<?  extends  ServerEndpointConfig.Configurator> configurator()
             default  ServerEndpointConfig.Configurator. class ;
}

一般情况下,我们只需要用为ServerEndpoint注解配置value属性,表示该端点映射的URL路径。

subprotocols协议用于配websocket的子协议,比如superchat等,这一阶段我们先不理会它。

decoders,encoders用于定义编解码器,后面的文章我们会详细讨论他。

configurator属性,对于声明式编程的Server端点,可以不配值,会采用默认值ServerEndpointConfig.Configurator即可。

(有默认值,一般说明该属性不可或缺,在编程式WebSocketk中时,我们会看到Configurator的更多细节).


DeclarativeServer实现四个方法,分别带有注解 @OnOpen,@OnClose,@OnMessage , @OnError标示。

@OnOpen表明当有客户端连接到该端点,则回调@OnOpen标记的方法。

@OnClose当客户端断开连接时,即服务端收到连接断开指定,则回调@OnClose的方法。

@OnMessage当服务端接收到清息时,则回调该方法。

@OnError当服务端发现异常情况时,比如协议错误,则回调该方法。Error不代表连接需要关闭,很多错误是可恢复的。


将该类打入war包,部署到Tomcat上,一个WebSocket服务端就OK了。


本次我们不用javascript作为Client端点,而是采用胖客户端模式访问,即Java Application。

首先定义Client端点:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@ClientEndpoint
public  class  DeclarativeClient {
     @OnOpen  
     public  void  onOpen(Session session) {  
        System.out.println( "I was accpeted by her!" );
     }  
   
     @OnClose  
     public  void  onClose() {  
     }  
   
     @OnMessage  
     public  void  onMessage(String message, Session session) { 
         System.out.println( "she say: "  + message); 
     }  
   
 
     @OnError  
     public  void  onError(Session session, Throwable error) {  
         error.printStackTrace();  
     }  
}

通过ClientEndpoint注解表示这是一个WebSocket的Client端点。

1
2
3
4
5
6
7
8
9
@Retention (RetentionPolicy.RUNTIME)
@Target (ElementType.TYPE)
public  @interface  ClientEndpoint {
     String[] subprotocols()  default  {};
     Class<?  extends  Decoder>[] decoders()  default  {};
     Class<?  extends  Encoder>[] encoders()  default  {};
     public  Class<?  extends  Configurator> configurator()
             default  Configurator. class ;
}

与上面的ServerEndpoint只差一个value属性,不用讲大家也知道为什么了。

各个方法注解与Server一样,不再重述。主函数:

1
2
3
4
5
6
7
8
9
public  class  Client {
     public  static  void  main(String[] args)  throws  DeploymentException, IOException, InterruptedException {
          WebSocketContainer ws = ContainerProvider.getWebSocketContainer();
          String url =  "ws://localhost:8080/ChatWeb/chat" ;
          Session session =  ws.connectToServer(DeclarativeClient. class , URI.create(url)); 
          session.getBasicRemote().sendText( "Hello,chick!" );
          Thread.currentThread().sleep( 10000 );
     }
}

运行Client之前,需要将Tomcat相关包导入,这里你可以全部导入,不再细说,有兴趣可自已研究。


ContainerProvider使有ServiceLoader机制加载ContainerProvider的实现类。并提供WebSocketContainer实例,

在Tomcat上,这个实例为WSWebSocketContainer类。

通过session.getBasicRemote()方法获取RemoteEndpoint.Basic实例来发送消息。

一个简单的WebSocket通信息就完成了。


本文转自 anranran 51CTO博客,原文链接:http://blog.51cto.com/guojuanjun/1963498

相关文章
学习websocket,原来这么简单
学习websocket,原来这么简单
|
5月前
|
移动开发 JavaScript 前端开发
webSocket 学习
vwebSocket 学习
25 0
|
8月前
|
前端开发 API
websocket使用实践代码指南
websocket使用实践代码指南
239 0
|
9月前
|
移动开发 网络协议 数据安全/隐私保护
谈谈你对webSocket的理解?
WebSocket是HTML5提供的一种浏览器与服务器进行全双工通讯的网络技术,属于应用层协议。它基于TCP传输协议,并复用HTTP的握手通道。浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接, 并进行双向数据传输。它最大的特点是:服务器可以向客户端主动推动消息,客户端也可以主动向服务器推送消息。
|
9月前
|
监控 网络协议 数据可视化
Websocket原理和实践
WebSocket是一种在单个TCP连接上进行全双工通信的协议。WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。
312 0
Websocket原理和实践
|
网络协议 前端开发 JavaScript
WebSocket的那些事(1-概念篇)
WebSocket的那些事(1-概念篇)
|
移动开发 JavaScript 前端开发
WebSocket 详解教程 上
WebSocket 详解教程 上
418 0
WebSocket 详解教程    上
|
XML 移动开发 Java
WebSocket 详解教程 下
WebSocket 详解教程 下
270 0
|
存储 JavaScript 网络协议
WebSocket接口初体验
这两天在调试一个WebSocket的接口,折腾了一天的时间终于弄好了。现在对WebSocket的相关知识点做一个记录。主要从如下几个方面进行介绍。
254 0
WebSocket接口初体验
|
缓存 JavaScript 网络协议