湖北山河建设集团网站,2345网址是啥,德山经济开发区建设局网站,wordpress mysql用户名密码WebSocket 简介 WebSocket 协议是基于 TCP 的一种新的网络协议#xff0c;它实现了浏览器与服务器全双工#xff08;full-duplex#xff09;通信—允许服务器主动发送信息给客户端#xff0c;这样就可以实现从客户端发送消息到服务器#xff0c;而服务器又可以转发消息到客…WebSocket 简介 WebSocket 协议是基于 TCP 的一种新的网络协议它实现了浏览器与服务器全双工full-duplex通信—允许服务器主动发送信息给客户端这样就可以实现从客户端发送消息到服务器而服务器又可以转发消息到客户端这样就能够实现客户端之间的交互。对于 WebSocket 的开发Spring 也提供了良好的支持目前很多浏览器已经实现了 WebSocket 协议但是依旧存在着很多浏览器没有实现该协议为了兼容那些没有实现该协议的浏览器往往还需要通过 STOMP 协议来完成这些兼容。
下面我们在 Spring Boot 中集成 WebSocket 来实现服务端推送消息到客户端。
Spring Boot 集成 WebSocket
首先创建一个 Spring Boot 项目然后在 pom.xml 加入如下依赖集成 WebSocket
dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-websocket/artifactId
/dependency
开启配置
接下来在 config 包下创建一个 WebSocket 配置类 WebSocketConfiguration在配置类上加入注解 EnableWebSocket表明开启 WebSocket内部实例化 ServerEndpointExporter 的 Bean该 Bean 会自动注册 ServerEndpoint 注解声明的端点代码如下
Configuration
EnableWebSocket
public class WebSocketConfiguration {Beanpublic ServerEndpointExporter serverEndpointExporter() {return new ServerEndpointExporter();}
}
编写端点服务类 接下来使用 ServerEndpoint 定义一个端点服务类在端点服务类中可以定义 WebSocket 的打开、关闭、错误和发送消息的方法具体代码如下所示
package worn.xiao.riskmsg.service;import com.alibaba.fastjson.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.atomic.AtomicInteger;ServerEndpoint(/websocket/{userId})
Component
public class WebSocketServer {private static final Logger log LoggerFactory.getLogger(WebSocketServer.class);/*** 当前在线连接数*/private static AtomicInteger onlineCount new AtomicInteger(0);/*** 用来存放每个客户端对应的 WebSocketServer 对象*/private static ConcurrentHashMapString, WebSocketServer webSocketMap new ConcurrentHashMap();/*** 与某个客户端的连接会话需要通过它来给客户端发送数据*/private Session session;/*** 接收 userId*/private String userId ;/*** 连接建立成功调用的方法*/OnOpenpublic void onOpen(Session session, PathParam(userId) String userId) {this.session session;this.userId userId;if (webSocketMap.containsKey(userId)) {webSocketMap.remove(userId);webSocketMap.put(userId, this);} else {webSocketMap.put(userId, this);addOnlineCount();}log.info(用户连接: userId ,当前在线人数为: getOnlineCount());try {sendMessage(连接成功);} catch (IOException e) {log.error(用户: userId ,网络异常!!!!!!);}}/*** 连接关闭调用的方法*/OnClosepublic void onClose() {if (webSocketMap.containsKey(userId)) {webSocketMap.remove(userId);subOnlineCount();}log.info(用户退出: userId ,当前在线人数为: getOnlineCount());}/*** 收到客户端消息后调用的方法** param message 客户端发送过来的消息*/OnMessagepublic void onMessage(String message, Session session) {log.info(用户消息: userId ,报文: message);if (!StringUtils.isEmpty(message)) {try {JSONObject jsonObject JSONObject.parseObject(message);jsonObject.put(fromUserId, this.userId);String toUserId jsonObject.getString(toUserId);if (!StringUtils.isEmpty(toUserId) webSocketMap.containsKey(toUserId)) {webSocketMap.get(toUserId).sendMessage(jsonObject.toJSONString());} else {log.error(请求的 userId: toUserId 不在该服务器上);}} catch (Exception e) {e.printStackTrace();}}}/*** 发生错误时调用** param session* param error*/OnErrorpublic void onError(Session session, Throwable error) {log.error(用户错误: this.userId ,原因: error.getMessage());error.printStackTrace();}/*** 实现服务器主动推送*/public void sendMessage(String message) throws IOException {this.session.getBasicRemote().sendText(message);}public static synchronized AtomicInteger getOnlineCount() {return onlineCount;}public static synchronized void addOnlineCount() {WebSocketServer.onlineCount.getAndIncrement();}public static synchronized void subOnlineCount() {WebSocketServer.onlineCount.getAndDecrement();}
}
其中ServerEndpoint(/websocket/{userId})表示让 Spring 创建 WebSocket 的服务端点其中请求地址是 /websocket/{userId}。
另外 WebSocket 一共有四个事件分别对应定义的 OnOpen、OnMessage、OnClose、OnError 注解。 OnOpen标注客户端打开 WebSocket 服务端点调用方法 OnClose标注客户端关闭 WebSocket 服务端点调用方法 OnMessage标注客户端发送消息WebSocket 服务端点调用方法 OnError标注客户端请求 WebSocket 服务端点发生异常调用方法 接下来启动项目使用 WebSocket 在线测试工具http://www.easyswoole.com/wstool.html进行测试有能力的也可以自己写个 html 测试。
测试html
!DOCTYPE html
html
head
meta charsetutf-8
titleJava后端WebSocket的Tomcat实现/title
script typetext/javascript srcjs/jquery.min.js/script
/head
body
div idmain stylewidth: 1200px;height:800px;/div
Welcomebr/input idtext typetext /
button onclicksend()发送消息/button
hr/
button onclickcloseWebSocket()关闭WebSocket连接/button
hr/
div idmessage/div
/body
script typetext/javascript
var websocket null;
//判断当前浏览器是否支持WebSocket
if(WebSocket in window) {
//改成你的地址
websocket new WebSocket(ws://192.168.100.196:8082/api/websocket/100);
} else {
alert(当前浏览器 Not support websocket)
}
//连接发生错误的回调方法
websocket.onerror function() {
setMessageInnerHTML(WebSocket连接发生错误);
};
//连接成功建立的回调方法
websocket.onopen function() {
setMessageInnerHTML(WebSocket连接成功);
}
var U01data, Uidata, Usdata
//接收到消息的回调方法
websocket.onmessage function(event) {
console.log(event);
setMessageInnerHTML(event);
setechart()
}
//连接关闭的回调方法
websocket.onclose function() {
setMessageInnerHTML(WebSocket连接关闭);
}
//监听窗口关闭事件当窗口关闭时主动去关闭websocket连接防止连接还没断开就关闭窗口server端会抛异常。
window.onbeforeunload function() {
closeWebSocket();
}
//将消息显示在网页上
function setMessageInnerHTML(innerHTML) {
document.getElementById(message).innerHTML innerHTML br/;
}
//关闭WebSocket连接
function closeWebSocket() {
websocket.close();
}
//发送消息
function send() {
var message document.getElementById(text).value;
websocket.send({msg: message });
setMessageInnerHTML(message #13;);
}
/script
/html
打开网页后在服务地址中输入ws://127.0.0.1:8088/websocket/xiaozhengwen点击开启连接按钮消息记录中会多一条由服务器端发送的连接成功记录。
接下来再打开一个网页服务地址中输入ws://127.0.0.1:8088/websocket/yangdandan点击开启连接按钮然后回到第一次打开的网页在消息框中输入
应用场景
1统计在线人数
2后台页面向客户端发送主动发送数据支持单发和群发