zoukankan      html  css  js  c++  java
  • 一个注解方式webSocket demo

    前段时间在研究websocket.其中遇到了一些bug。这里跟大家分享这过程。

    首先介绍一下websocket

    WebSocket是HTML5的一种新协议,实现了浏览器和服务器的双全工通信,能更好的节省服务器资源和带宽并达到实时通信。同时WebSocket是建立在TCP之上,同HTTP一样通过TCP来通信。WebSocket需要类似TCP的客户端和服务端的握手连接然后进行通信。但websocket与传统的HTTP每次请求-应答都需要客户端和服务端建立连接模式不同的是websocket类似socket的TCP长连接的通讯模式,在客户端断开websocket连接或服务端断开连接前,不需要客户端和服务端重新发起连接请求。一旦websocket建立连接之后,后续的数据都是以帧序列的形式传输。

    此websocket demo的后台使用的是Java写的,如下:

     1 import java.util.concurrent.CopyOnWriteArraySet;
     2 
     3 import javax.websocket.OnClose;
     4 import javax.websocket.OnError;
     5 import javax.websocket.OnMessage;
     6 import javax.websocket.OnOpen;
     7 import javax.websocket.Session;
     8 import javax.websocket.server.ServerEndpoint;
     9 
    10 
    11 @ServerEndpoint("/myecho")
    12 public class WSDemo {
    13 
    14 //    Logger log = Logger.getLogger(getClass());
    15     
    16     //当前在线人数
    17     private static int onlineCount = 0;
    18     //用一个set集合保存几个websocket实例
    19     private static CopyOnWriteArraySet<WSDemo> wsSet = new CopyOnWriteArraySet<WSDemo>();
    20     //websocket的session
    21     private Session session;
    22     
    23     /**
    24      * 客户端新建websocket时会触发(握手协议后)
    25      * 并加入当前的set集合中
    26      * @param session
    27      */
    28     @OnOpen
    29     public void wsOpen(Session session) {
    30         this.session = session;
    31         wsSet.add(this);//加入集合
    32         // 在线人数加1
    33         addOnlineCount();
    34     }
    35     
    36     //当websocket退出的时候触发,并在set集合中删除当前websocket
    37     @OnClose
    38     public void wsClose(){
    39         wsSet.remove(this); //删除
    40         //在线人数-1
    41         subOnlineCount();
    42     }
    43     
    44     /**
    45      * 接收到客户端发来的消息并处理,同时也像客户端发送消息
    46      * @param message
    47      * @param session
    48      */
    49     @OnMessage
    50     public void wsMessage(String message, Session session) {
    51         sendMessage(message);
    52         System.out.println("=====客户端发来消息:" + message);
    53         System.out.println("======websocket 数量:" + wsSet.size());
    54         //群发消息
    55         for(WSDemo wss: wsSet) {
    56             wss.sendMessage("服务端发来的消息"); //向客户端发送消息
    57         }
    58     }
    59     
    60     //websocket错误的时候丢出一个异常
    61     @OnError
    62     public void wsError(Session session, Throwable throwable) {
    63         throw new IllegalArgumentException(throwable);
    64     }
    65     
    66     //send message  发送消息处理方法
    67     public void sendMessage(String message) {
    68         try {
    69             this.session.getBasicRemote().sendText(message);
    70             System.out.println("===============发送了消息:" + message);
    71         } catch (Exception e) {
    72             // TODO: handle exception
    73             System.out.println(e.getMessage());
    74         }
    75     }
    76     
    77     // get onlinecount
    78     public static synchronized int getOnlineCount() {
    79         return onlineCount;
    80     }
    81     
    82     // +1
    83     public static synchronized void addOnlineCount() {
    84         WSDemo.onlineCount++;
    85         System.out.println("++++++++++++++上线人数+1:" + onlineCount);
    86     }
    87     
    88     //-1
    89     public static synchronized void subOnlineCount() {
    90         WSDemo.onlineCount--;
    91         System.out.println("---------------线上人数-1:" + onlineCount);
    92     }
    93     
    94 }

    前端代码就相对简单,直接使用我们注册的'/myecho' websocket服务端

    var wsuri = "ws://localhost:8080/wsdemo/myecho";
    var ws = null;
    
    function dows() {
            //判断浏览器是否支持websocket
        if("WebSocket" in window || window.WebSocket) {
            ws = new WebSocket(wsuri);
        } else {
            alert("browser not support websocket...");
    //        throw "browser not support websocket..."; //这种写法是可以的
            throw new Error("browser not support websocket...");//这种也是可以
            return false
        }
        ws.onopen = function(evt) {
            wsObj.wsopen(evt);
        }
        ws.onmessage = function(evt) {
            wsObj.wsmsg(evt);
        }
        ws.onclose = function(evt) {
            wsObj.wsclose(evt);
        }
        ws.onerror = function(evt) {
            wsObj.wserror(evt);
        }
        /*ws.send("my message...");*/
    }
    
    var wsObj = {
        wsopen:function(evt) {
            console.log(evt.type);
            document.querySelector("#clientSuc").innerHTML = "websocket connect success...";
        },
        wsmsg:function(msg) {
            debugger;
            console.log("type:"+msg.type);
            //document.getElementById("msg").innerHTML = msg.data;
            console.log("data:" + msg.data);
            document.querySelector("#msg").innerHTML = msg.data;
    //        ws.close(); //关闭websocket
        },
        wsclose:function(evt) {
            console.log("type:" + evt.type);
        },
        wserror:function(evt) {
            console.log("type:" + evt.type);
        }
    };
    function sendMsg (){
        var msg = "hello websocket...";
        ws.send(msg);
    }
    function closeWebsocket() {
        ws.close();
    }
    
    window.addEventListener("load", dows, false);

    这里需要注意到的是:因为websocket是j2ee 7 以上的版本所以需要jdk版本1.7以上,而且tomcat服务器的支持也有区别,比如tomcat7不会自动把'websocket-api.jar'引入,而tomcat8则会。如果使用tomcat7的版本且没有自己手动添加tomcat的library引入'websocket-api.jar'这个jar包的话前台会报404找不到websocket服务的异常。这个bug我搞了半天才知道原来是tomcat版本的问题。

  • 相关阅读:
    Java实现约瑟夫环问题
    Java实现约瑟夫环问题
    mysql远程表链接
    linux下mysql定时备份
    深入浅出RPC——浅出篇(转载)
    深入浅出RPC——深入篇(转载)
    Qt在Windows上的调试器安装与配置
    VS2015 ASP.NET5 Web项目
    jquery validate remote验证唯一性
    jQuery UI框架
  • 原文地址:https://www.cnblogs.com/leungUwah/p/5327321.html
Copyright © 2011-2022 走看看