一个注解方式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版本的问题。

原文地址:https://www.cnblogs.com/leungUwah/p/5327321.html