当前位置:网站首页>使用websocket实现服务端主动发送消息到客户端
使用websocket实现服务端主动发送消息到客户端
2022-08-08 06:26:00 【写做四月一日的四月一日】
平时我们都是由客户端浏览器主动发送请求到服务端,然后服务器处理请求后返回结果,服务器无法主动向客户端浏览器发送消息。
但是在某些业务场景下我们需要由服务器主动发送消息到客户端浏览器,如当客户用户下订单后,服务器需要主动发消息提醒商户用户有新的订单被创建,请及时处理。在这种需求下我们就需要使用到websocket。
WebSocket是一种在单个TCP连接上进行全双工通信的协议。
下面来看一看websocket的使用示例:
前端代码
创建一个发送消息到服务端的页面sendMessage.html,模拟用户下订单
通过ajax方式发送消息到服务端
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
输入需要发送的消息:<input type="text" id="sendText">
<input type="button" id="sendBtn" value="发送消息">
</body>
<script>
var sendText = document.getElementById('sendText');
var sendBtn = document.getElementById('sendBtn');
//按下按钮后通过ajax发送消息到服务端
sendBtn.onclick = function () {
var send = sendText.value;
var xmlHttp = new XMLHttpRequest();
var url = "/sendMessage?msg=" + send;
console.log(url);
xmlHttp.open("get",url,true);
xmlHttp.send();
}
</script>
</html>创建一个接收服务端消息的页面websocketPage.html,模拟商户接收到消息
这里只是将接收到的消息展示在页面上,也可以做成弹出弹窗、消息图标显示角标等其它形式。
注意:websocket协议的url是以ws开头的而不是http!
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
消息展示区:<br/>
<div id="textArea"></div>
</body>
<script>
var textArea = document.getElementById('textArea');
var websocket = null;
//如果浏览器支持websocket就建立一个websocket,否则提示浏览器不支持websocket
if('websocket' in window){
websocketPage = new WebSocket('ws://localhost:8080/websocketurl');
}else{
alert('浏览器不支持websocket!');
}
//建立websocket时自动调用
websocketPage.onopen = function (event) {
console.log('建立连接');
}
//关闭webscoket时自动调用
websocketPage.oncolse = function (event){
console.log('关闭连接');
}
//websocket接收到消息时调用
websocketPage.onmessage = function (event){
//将接收到的消息展示在消息展示区
textArea.innerText += event.data;
textArea.innerHTML += "<br/>";
}
//websocket出错自动调用
websocketPage.onerror = function () {
alert('websocket出错');
}
//关闭窗口前关闭websocket连接
window.onbeforeunload = function (){
websocketPage.close();
}
</script>
</html>后端代码
在springboot项目中引入websocket依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>创建一个websocket服务点导出器
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
@Configuration
public class WebsocketConfig {
@Bean
public ServerEndpointExporter getServerEndpointExporter(){
return new ServerEndpointExporter();
}
}
创建一个websocket服务类
import org.springframework.stereotype.Component;
import javax.websocket.OnClose;
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.CopyOnWriteArraySet;
@Component
@ServerEndpoint("/websocketurl")//设置websocket连接url,就是前端创建websocket需要提供的url
public class MyWebSocketService {
private Session session;
//存放所有的websocket连接
private static CopyOnWriteArraySet<MyWebSocketService> myWebSocketServicesSet = new CopyOnWriteArraySet<>();
//建立websocket连接时自动调用
@OnOpen
public void onOpen(Session session){
this.session = session;
myWebSocketServicesSet.add(this);
System.out.println("有新的websocket连接进入,当前连接总数为" + myWebSocketServicesSet.size());
}
//关闭websocket连接时自动调用
@OnClose
public void onClose(){
myWebSocketServicesSet.remove(this);
System.out.println("连接断开,当前连接总数为" + myWebSocketServicesSet.size());
}
//websocket接收到消息时自动调用
@OnMessage
public void onMessage(String message){
System.out.println("this:" + message);
}
//通过websocket发送消息
public void sendMessage(String message){
for (MyWebSocketService webSocketService : myWebSocketServicesSet){
try {
webSocketService.session.getBasicRemote().sendText(message);
} catch (IOException e) {
System.err.println(this + "发送消息错误:" + e.getClass() + ":" + e.getMessage());
}
}
}
}创建一个接收创建订单信息的控制器
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import xyz.syyrjx.websockettest.websocketService.MyWebSocketService;
import javax.annotation.Resource;
@Controller
public class MyController {
@Resource
MyWebSocketService webSocketService;
@RequestMapping("/sendMessage")
@ResponseBody
public Object sendMessage(String msg){
webSocketService.sendMessage(msg);
return null;
}
}规定url和视图的映射关系
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class MVCConfiguration implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/websocketPage").setViewName("websocketPage");
registry.addViewController("/sendMessagePage").setViewName("sendMessage");
}
}启动项目进行测试
启动一个edge浏览器,进入websocketPage页面等待消息,服务端接收到websocket连接,打印当前连接数

启动一个chrome浏览器,进入sendMessagePage页面发送消息

在sendMessagePage页面输入消息并发送,在websocketPage页面就会接收到消息并展示,此时websocketPage没有主动发送请求给服务器,而是服务器主动发送消息给浏览器

边栏推荐
- ps神经网络滤镜安装包,ai神经网络滤镜安装包
- 【EagleEye】2020-ECCV-EagleEye: Fast Sub-net Evaluation for Efficient Neural Network Pruning-论文详解
- NVIDIA CUDA 高度并行处理器编程(九):并行模式:稀疏矩阵-向量乘法
- 【图形学】13 UnityShader语义(一)
- 模块及模块导入
- C# Unicode(万国码)文字转换
- Unity HDRP下VRTK传送、穿墙 时画面淡入淡出、视觉遮挡无法正确显示问题解决
- 深度神经网络的训练过程,深度神经网络训练方法
- ResNet网络结构详解、完整代码实现
- Unity 物体颜色渐变效果(判断逻辑实现)
猜你喜欢
随机推荐
【图形学】12 UnityShader语法入门
栈队列OJ题分享及讲解
P21 美颜相机的实现——提速,重绘,撤回
NVIDIA CUDA 高度并行处理器编程(四):性能优化习题
神经网络预测值几乎一样,神经网络为什么能预测
RHCSA-配置redhat
win11+MX250+CUDA Tookit 10.1 update 2
How to get all child objects under an object in Unity
虚拟机克隆 快照 迁移 删除
《Filter Pruning using Hierarchical Group Sparse》ICPR2020论文详解
【图形学】15 UnityShader语义(三)
网络配置——静态路由内网以及外网连接
Unity_对象池
NVIDIA CUDA Highly Parallel Processor Programming (6): Parallel Mode: Convolution
二分查找一个数首次与最后出现的位置
有符号数和无符号数参与运算时的问题
神经网络的图像识别技术,神经网络的层数怎么看
Chained queue push and pop related operations
ESP32 温湿度和气体传感器驱动
[总结] Unity Lightmap使用总结









