zoukankan      html  css  js  c++  java
  • java版Web Socket,实现消息推送

    # web socket是什么?

    WebSocket协议是基于TCP的一种新的网络协议。

    它实现了浏览器与服务器全双工(full-duplex)通信,允许服务器主动发送信息给客户端

    ## 用途

    实时Web应用的解决方案,实现Web的实时通信。

    说的再直白点,html的消息推送

    假如你有一个页面,数据不定期更改,通常的做法就是轮询,客户端不停地向服务器请求最新的数据。

    当有了web socket,数据变动时 让服务器通知客户端,启不是很美妙?

    ## 请求示例

    (1) 默认端口是80和443(ssl)。

    (2) 协议标识符是ws和ws(ssl)。

    (3) 请求报文示例

    General
    --------------------------------------------
    Request URL:ws://localhost:8080/j2ee-websocket/websocket/1
    Request Method:GET
    Status Code:101 Switching Protocols
    ---------------------------------------------
    Response Headers
    ---------------------------------------------
    Connection:upgrade
    Date:Tue, 05 Dec 2017 01:22:45 GMT
    Sec-WebSocket-Accept:cRxT/XcOpnsleDb1KdydWXOw+us=
    Sec-WebSocket-Extensions:permessage-deflate;client_max_window_bits=15
    Server:Apache-Coyote/1.1
    Upgrade:websocket
    web socket request

    # 代码实现

    代码分为3个部分:javax.websocket api实现,使用观察者模式增强,google/jquery-websocket代码库。

    完整代码地址,开箱即用。github:j2ee-websocket

    ## 服务端 java代码 

    jar -- 引入javax.websocket,或引入javaee-api。

    这里只展示api接口特性。

    /**
    *Web Socket api implement
    *参数以URL路径参数传递
    */
    @ServerEndpoint(value = "/websocket/{principal}")
    public class DefaultWebSocket {
    
        /** Web Socket连接建立成功的回调方法 */
        @OnOpen
        public void onOpen(@PathParam("principal") String principal, Session session) {
        //... }
    /** 服务端收到客户端发来的消息 */ @OnMessage public void onMessage(@PathParam("principal") String principal, String message, Session session) {     //... } @OnClose public void onClose(@PathParam("principal") String principal, Session session) {
        //... } @OnError
    public void onError(@PathParam("principal") String principal, Session session, Throwable error) { //... } }

    ## 服务端推送消息至客户端 java代码

    这里使用了 观察者模式,对websocket进行了增强,详见完整代码:github:j2ee-websocket

         /**服务端向客户端推送消息*/
            public void notifyTest() {
                String principal = "1";
                String type = "radio";
                JSONObject data = new JSONObject();
                data.put("title", "test web socket");
                data.put("content", "Have you recieve this msg?--this msg from server.");
    
                WebSocketSubject subject = WebSocketSubject.Holder.getSubject(principal);
                subject.notify(type, data.toJSONString());
            }

    ## 客户端 javascript代码

    普通js代码

    <script type="text/javascript">  
          var websocket = null;  
          var principal = '1';
          var socketURL = 'ws://' + window.location.host
                + '/j2ee-websocket/websocket/' + principal;
          //判断当前浏览器是否支持WebSocket  
          if('WebSocket' in window){  
              websocket = new WebSocket(socketURL);  
          }  
          else{  
              alert('Not support websocket');  
          }  
             
          //连接发生错误的回调方法  
          websocket.onerror = function(event){  
              alert("error");  
          };  
             
          //连接成功建立的回调方法  
          websocket.onopen = function(){  
              alert("open");  
          }  
             
          //接收到消息的回调方法  
          websocket.onmessage = function(event){  
              alert('recive : ' + event.data);  
          }  
             
          //连接关闭的回调方法  
          websocket.onclose = function(event){  
              alert("close");  
          }  
             
          //发送消息  
          function send(message){  
              websocket.send(message);  
          }  
      </script>
    web socket js

    推荐:google/jquery-websocket代码 (http://code.google.com/p/jquery-websocket)

    google/jquery-websocket增加了消息的类型,将消息拆分为{"type":"","message":""}。

    这样更灵活,可以根据业务类型,定义type,如:通知,公告,广播,发文等...

    <script type="text/javascript">
            var principal = '1';
            var socketURL = 'ws://' + window.location.host
                    + '/j2ee-websocket/websocket/' + principal;
            
            websocket = $.websocket(socketURL, {
                open : function() {
                    // when the socket opens
                    alert("open");
                },
                close : function() {
                    // when the socket closes
                    alert("close");
                },
                //收到服务端推送的消息处理
                events : {
                    'radio' : function(event) {
                        console.info($.parseJSON(event.data));
                    },
                    'notice' : function(event) {
                        console.info($.parseJSON(event.data));
                    },
                    //... more custom type of message
                }
            });
            
            //发送消息  
            function send() {
                websocket.send('radio', " hello,this msg from client request");
            }
        </script>

     # 客户端运行示例

    --END--

  • 相关阅读:
    HDU 1166 敌兵布阵 我的第一棵树,线段树,树状数组。
    HDU 2544 最短路 第一个图论问题。
    位运算简介及实用技巧(三):进阶篇(2)
    用匈牙利算法求二分图的最大匹配
    求两个字符串的最长公共子序列的长度(动态规划)
    搜索之深度优先【迷宫搜索】(判断是否n步恰好可以到达某点)
    HDU 2955 Robberies
    STL简介
    HDU 1257 最少拦截系统
    HDU 2034 人见人爱AB
  • 原文地址:https://www.cnblogs.com/svili/p/7985608.html
Copyright © 2011-2022 走看看