springboot整合websocket进行消息推送
什么是websocket?
WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议,使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。
WebSocket消息推送流程
由于springboot创建项目相对比较简单,配置也很简单
使用idea创建一个springboot项目
需要的依赖:
选上这几个就够了
pom文件:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.4.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.xiaomifeng1010</groupId><artifactId>websocketdemo</artifactId><version>0.0.1-SNAPSHOT</version><packaging>war</packaging><name>websocketdemo</name><description>Demo project for Spring Boot</description><properties><java.version>1.8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><scope>runtime</scope><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-tomcat</artifactId><scope>provided</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope><exclusions><exclusion><groupId>org.junit.vintage</groupId><artifactId>junit-vintage-engine</artifactId></exclusion></exclusions></dependency><dependency><groupId>org.springframework.amqp</groupId><artifactId>spring-rabbit-test</artifactId><scope>test</scope></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>
项目结构:
前端文件放在static文件夹下:
show.html
<!DOCTYPE html>
<html><head>
<meta charset="UTF-8">
<title>测试websocket点对点发送</title>
<script src="js/websocket.js"></script>
<script src="js/jquery.min.js"></script>
<script src="js/sockjs.min.js"></script>
<script src="js/stomp.min.js"></script>
<script id="code">var DEBUG_FLAG = true;$(function(){//启动websocketconnect();});function send() {var msg = $("#msg").val();stompClient.send("/send", {}, msg);}function sendToUser() {var msg = $("#msg").val();var toUserId = $("#userId").val();var data = {"fromUserId": userId, "toUserId": toUserId, "msg": msg};stompClient.send("/sendToUser", {}, JSON.stringify(data));}
</script>
</head><body style="margin: 0px;padding: 0px;overflow: hidden; "><!-- 显示消息--><textarea id="debuggerInfo" style="width:100%;height:200px;"></textarea><!-- 发送消息--><div>用户:<input type="text" id="userId"></input></div><div>消息:<input type="text" id="msg"></input></div><div><input type="button" value="发送消息" onclick="sendToUser()"></input></div>
</body>
</html>
js文件有三个min.js的是开源库需要自己下载,还有一个js文件websocket.js是自定义的js文件
websocket.js
var stompClient = null;
var wsCreateHandler = null;
var userId = null;function connect() {var host = window.location.host; // 带有端口号userId = GetQueryString("userId");var socket = new SockJS("http://" + host + "/websocket");stompClient = Stomp.over(socket);stompClient.connect({}, function (frame) {writeToScreen("connected: " + frame);stompClient.subscribe('/topic', function (response) {writeToScreen(response.body);});stompClient.subscribe("/user/" + userId + "/topic", function (response) {writeToScreen(response.body);});stompClient.subscribe('/sendToAll', function (response) {writeToScreen("sendToAll:" + response.body);});}, function (error) {wsCreateHandler && clearTimeout(wsCreateHandler);wsCreateHandler = setTimeout(function () {console.log("重连...");connect();console.log("重连完成");}, 1000);})
}function disconnect() {if (stompClient != null) {stompClient.disconnect();}writeToScreen("disconnected");
}function writeToScreen(message) {if(DEBUG_FLAG){$("#debuggerInfo").val($("#debuggerInfo").val() + "\n" + message);}
}function GetQueryString(name) {var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");var r = window.location.search.substr(1).match(reg); //获取url中"?"符后的字符串并正则匹配var context = "";if (r != null)context = r[2];reg = null;r = null;return context == null || context == "" || context == "undefined" ? "" : context;
}
后端的配置及代码
application.properties中只配置了服务器端口就可以了
server.port=8939
启动类和servlet初始化类
package com.xiaomifeng1010.websocket;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class WebsocketdemoApplication {public static void main(String[] args) {SpringApplication.run(WebsocketdemoApplication.class, args);}}
package com.xiaomifeng1010.websocket;import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;public class ServletInitializer extends SpringBootServletInitializer {@Overrideprotected SpringApplicationBuilder configure(SpringApplicationBuilder application) {return application.sources(WebsocketdemoApplication.class);}}
这项目中有两个项目包configuration包和controller包
配置类:
package com.xiaomifeng1010.websocket.configuration;import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {@Overridepublic void registerStompEndpoints(StompEndpointRegistry registry){//客户端连接端点registry.addEndpoint("/websocket").setAllowedOrigins("*").withSockJS();}
}
@@EnableWebSocketMessageBroker 作用是开启websocket服务,registerStompEndpoints方法配置websocket消息服务端
controller类
package com.xiaomifeng1010.websocket.controller;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;import java.util.Map;@RestController
public class WebsocketController {@Autowiredprivate SimpMessagingTemplate template;@MessageMapping("/sendToAll")public String sendToAll(String msg) {return msg;}@MessageMapping("/send")@SendTo("/topic")public String say(String msg) {return msg;}@MessageMapping("/sendToUser")public void sendToUserByTemplate(Map<String,String> params) {String fromUserId = params.get("fromUserId");String toUserId = params.get("toUserId");String msg = "来自" + fromUserId + "消息:" + params.get("msg");template.convertAndSendToUser(toUserId,"/topic", msg);}@GetMapping("/sendToAllByTemplate")@MessageMapping("/sendToAllByTemplate")public void sendToAllByTemplate(@RequestParam String msg) {template.convertAndSend("/topic", msg);}@GetMapping("/send")public String msgReply(@RequestParam String msg) {template.convertAndSend("/topic", msg);return msg;}
}
@MessageMapping的作用类似@requestMapping的作用,声明请求映射路径的
现在的show.html文件中发请求是发到"/sendToUser"这个请求的
@MessageMapping("/sendToUser")
public void sendToUserByTemplate(Map<String,String> params) {
String fromUserId = params.get("fromUserId");
String toUserId = params.get("toUserId");
String msg = "来自" + fromUserId + "消息:" + params.get("msg");
template.convertAndSendToUser(toUserId,"/topic", msg);
}
可以从show.html文件中看出
启动springboot项目,然后在浏览器中访问show.html
访问成功,会展示连接信息
请求中带上userId参数,表示fromUser的值,用户对应的文本输入框输入的是toUser的值
toUser值的获取:
fromUser值的获取:
是从get请求中获取的参数值
发送消息的时候,直接使用的是stompClient发送的请求
后端代码:
在刚才的那个窗口 浏览器地址栏输入的userId=1,用户的文本框输入的也是1(那么当前打开的窗口就是1号客户端,fromUser和toUse都是1,相当于1号自己给自己发信息,服务端的信息还是返回给了1号,可以看到信息来自1,消息是4)
可以多开几个页面窗口,模拟多个消息发送窗口
在开一个用户2,给1号发送消息5
然后查看1号用户窗口:
可以看到2号用户给1号用户发送的信息5
再开一个窗口,模拟3号用户
然后从1号用户窗口给3号发信息233
再观察3号用户窗口:
可以看到1号用户发送的信息233,从而实现了点对点,用户对精确目标用户来发送信息 。
在任何一个用户的窗口,F12查看network都可以
然后看websocket请求
可以看到http请求,http协议升级成了websocket协议(ws),requestURL是以ws开头而不是http开头了,connection的值是upgrade (升级)了
springboot整合websocket进行消息推送相关推荐
- springboot整合websocket实现消息推送
springboot整合websocket 1.WebSocket介绍与原理 介绍:WebSocket是HTML5一种新的协议.它实现了浏览器与服务器全双工通信.一开始的握手需要借助HTTP请求完成. ...
- springboot定时发送短信_springboot 整合websocket实现消息推送(主动推送,具体用户推送,群发,定时推送)...
websocket springboot 整合websocket实现消息推送(主动推送,具体用户推送,群发,定时推送) 使用WebSocket构建交互式Web应用程序 本指南将引导您完成创建" ...
- java整合消息推送_SpringMVC整合websocket实现消息推送及触发功能
本文为大家分享了SpringMVC整合websocket实现消息推送,供大家参考,具体内容如下 1.创建websocket握手协议的后台 (1)HandShake的实现类 /** *Project N ...
- Springboot集成websocket实现消息推送和在线用户统计
一.HTTP 说到websocket首先要说Http,Http大家都知道是一个网络通信协议,每当客户端浏览器需要访问后台时都会发一个请求,服务器给出响应后该连接就会关闭,请求只能有客户端发起,服务端是 ...
- SpringMVC整合websocket实现消息推送及触发
2019独角兽企业重金招聘Python工程师标准>>> 1.创建websocket握手协议的后台 (1)HandShake的实现类 [java] view plain copy /* ...
- 【微信小程序】1、SpringBoot整合WxJava开启消息推送
接入微信小程序消息推送服务,可以3种方式选择其一: 1.开发者服务器接收消息推送 2.云函数接收消息推送 3.微信云托管服务接收消息推送 开发者服务器接收消息推送,开发者需要按照如下步骤完成: 1.填 ...
- Vue-全局websocket 实现消息推送
在上一篇文章 WebSocket 消息推送https://blog.csdn.net/qq_63312957/article/details/125375122?spm=1001.2014.3001. ...
- springboot集成webSocket实现实时推送
springboot集成webSocket实现实时推送 webSocket实现推送 webSocket是什么? 需求说明 websocket集成步骤 pom.xml webSocket实现 自定义处理 ...
- php通知websocket,php实现websocket实时消息推送
php实现websocket实时消息推送,供大家参考,具体内容如下 SocketService.php /** * Created by xwx * Date: 2017/10/18 * Time: ...
最新文章
- 列表组件之RecyclerView
- javascript实战pdf_javascript该怎么学呢?学习Js之路
- 【Android压力测试】monkey压力测试
- 基于AliOS Things玩转智能语音
- php图片遍历,php – 如何遍历图像的所有像素?
- python适配器模式角色_适配器模式(Adapter模式)详解
- maven package 打包报错 Failed to execute goal
- 七周成为数据分析师 第四周:数据可视化
- http,https,spdy,http2等协议的主要区别详解
- 计算机电源 通电,笔记本电脑开不了机,通电后电源指示灯不亮
- 华为公有云接口的问题
- Xshell 连接服务器失败的解决方法
- 三论 (信息论、控制论、系统论的合称)
- 数据库界的《延禧攻略》来了,不看你就输了
- 艰难2020:人工智能的应用是否已停滞不前?
- 解决UnicodeDecodeError: ‘utf-8‘ codec can‘t decode byte 0xca in position 0: invalid continuation byte
- 函数的奇偶性、周期性和单调性
- 饥荒联机版Mod开发——两种帽子(十)
- ttylinux tomcat问题
- 在这个人人都想暴富的时代,学会我交给你的Python躺赚大法,带你走进尔康的生活。