1、浏览器通过JavaScript 向服务器端发出建立WebScoket连接的请求,连接建立成功之后,开始长链接
2、客户端和服务端就可以通过TCP连接传输数据因为WebSocket连接本质时TCP,所以不需要每次传输都带上重复的头部数据,所以数据传输比轮询和Comet技术小了很多。
需要导入两个jar包
链接:https://pan.baidu.com/s/1UOWCg354bRpATXJIaKACvg
提取码:8gd4
- HTML部分
<button id="connBtn">连接</button>
<input type="text" id="msg">
<button id="sendBtn" οnclick="send()">发送</button>
<button id="closeBtn" οnclick="closeWebsocket()">关闭</button>
<div id="message">
</div>
2.Javascript 部分
<script>
var ws = null;
if ('WebSocket' in window){
ws = new WebSocket("ws:localhost:8081/websocket")
}else {
alert("浏览器不支持");
}
var connBtn = document.getElementById("connBtn");
var sendBtn = document.getElementById("sendBtn");
var closeBtn = document.getElementById("closeBtn");
// 连接安生错误的回调方法
ws.onerror = function () {
setMessageInnerHTML("WEBSOCKET发生链接错误");
}
// 连接成功的回调方法
ws.onopen = function (ev) {
setMessageInnerHTML("WebSocket连接成功!");
}
// 收到消息的回调方法
ws.onmessage = function (ev) {
console.log(1)
setMessageInnerHTML(ev.data);
}
// 连接关闭的回调方法
ws.onclose = function () {
setMessageInnerHTML("WebSocket连接关闭");
}
// 监听窗口关闭事件,防止连接没断关闭窗口。
window.onbeforeunload = function () {
closeWebSocket();
}
// 将消息显示在网页上
function setMessageInnerHTML(innerHtml){
document.getElementById("message").innerHTML += innerHtml + '<br />'
}
// 关闭websocket连接
function closeWebsocket(){
ws.close();
}
// 发送消息
function send(){
var message = document.getElementById("msg").value;
ws.send(message);
}
</script>
3.JavaWeb后端代码
package com.gss.socket;
import com.sun.istack.internal.logging.Logger;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;
@ServerEndpoint(value = "/websocket")
public class WebSocketTest {
private static Logger logger = Logger.getLogger(WebSocketTest.class);
//线程安全的静态变量,表示在线连接数
private static volatile int onlineCount = 0;
//用来存放每个客户端对应的WebSocketTest对象,适用于同时与多个客户端通信
public static CopyOnWriteArraySet<WebSocketTest> webSocketSet = new CopyOnWriteArraySet<WebSocketTest>();
//若要实现服务端与指定客户端通信的话,可以使用Map来存放,其中Key可以为用户标识
public static ConcurrentHashMap<Session, Object> webSocketMap = new ConcurrentHashMap<Session, Object>();
//与某个客户端的连接会话,通过它实现定向推送(只推送给某个用户)
private Session session;
/**
* 建立连接成功调用的方法
*/
@OnOpen
public void onOpen(Session session) {
this.session = session;
webSocketSet.add(this); // 添加到set中
webSocketMap.put(session,this); // 添加到map中
addOnlineCount(); // 添加在线人数
System.out.println("新人加入,当前在线人数为:" + getOnlineCount());
}
/**
* 关闭连接调用的方法
*/
public void onClose(Session closeSession){
webSocketMap.remove(session);
webSocketSet.remove(this);
subOnlineCount();
System.out.println("有人离开,当前在线人数为:" + getOnlineCount());
}
/**
* 收到客户端小心调用的方法
*/
@OnMessage
public void onMessage(String message,Session mysession) throws Exception{
for (WebSocketTest item:
webSocketSet) {
item.sendAllMessage(message);
}
}
public void sendAllMessage(String message) throws IOException {
this.session.getBasicRemote().sendText(message);
}
// 获取在线人数
public static synchronized int getOnlineCount(){
return onlineCount;
}
// 添加在线人+1
public static synchronized void addOnlineCount(){
onlineCount ++;
}
// 减少在线人-1
public static synchronized void subOnlineCount(){
onlineCount --;
}
}
少jar包 找jar即可
参考https://blog.youkuaiyun.com/qq_40990836/article/details/83892640