springboot集成websocket
admin
2024-03-27 19:16:17
0

简介

STOMP的全称是Simple (or Streaming) Text Orientated Messaging Protocol,一种简单的流式文本传输协议。对于不支持websocket的浏览器我们需要通过STOMP来兼容,兼容的需要俩个组件,一个是前端需要的SockJs,一个是后端需要的WebSocketMessageBroker。SockJs一种让前端可以支持socket通信的技术解决方案,WebSocketMessageBroker是基于消息组件实现的一种通信协议。

实现

一、在后端springboot服务中添加依赖

org.springframework.bootspring-boot-starter-websocket2.2.6.RELEASE

二、添加websocketConfig

import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;/*** @author liqiang*/
@Slf4j
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {@Overridepublic void registerStompEndpoints(StompEndpointRegistry registry) {// 增加一个后端服务端点registry.addEndpoint("/socket").setAllowedOrigins("*").withSockJS();// 增加一个前端服务端点registry.addEndpoint("/wsuser").setAllowedOrigins("*").withSockJS();// 配置客户端尝试连接地址
//        registry.addEndpoint("/ws").setAllowedOrigins("*").withSockJS();}/*** 定义服务器端点请求和订阅前缀* @param registry*/@Overridepublic void configureMessageBroker(MessageBrokerRegistry registry) {// 客户端订阅路径前缀registry.enableSimpleBroker("/sub", "/user");// 服务端点请求前缀registry.setApplicationDestinationPrefixes("/request");// 设置广播节点/*registry.enableSimpleBroker("/topic", "/user");// 客户端向服务端发送消息需有/app 前缀registry.setApplicationDestinationPrefixes("/app");*/// 指定用户发送(一对一)的前缀 /user/registry.setUserDestinationPrefix("/user/");}
}

解释:
1、

 registry.addEndpoint("/socket").setAllowedOrigins("*").withSockJS();

addEndpoint添加一个端点,用于前端创建socket连接,在示例中我们创建了俩个端点,这里传差的使用互补影响,不如我发送的时候创建链接使用的是socket端点,而接收信息的时候使用的wsuser端点,这样也是可以互通信息的。
setAllowedOrigins(“*”)这个是设置跨域的。

2、

registry.enableSimpleBroker("/sub", "/user");

设置客户端订阅的前缀

registry.setApplicationDestinationPrefixes("/request");

设置前端请求后端发送信息的前缀

registry.setUserDestinationPrefix("/user/");

设置一对一转发信息时的用户前缀

三、实现广播方式

1、前端代码

1.1 发送信息前端代码



websocket STOMP


websocket兼容STOMP测试11

跳转到消息接收页

1.2接收信息前端代码



websocket-stomp-receive





等待接收消息

解释:
在前端代码中主要的发送信息和接收信息的部分在js中,如下截取出来:

var stompClient = null;// 设置连接function connect() {// 定义请求服务器的端点var socket = new SockJS('/socket');// stomp客户端stompClient = Stomp.over(socket);// 连接服务器端点stompClient.connect({}, function (frame) {// 建立连接后的回调,这个是设置连接状态的setConnected(true);})}// 断开socket连接function disconnect() {if (stompClient != null) {stompClient.disconnect();}setConnected(false);console.log("Disconnected");}// 向/request/send服务端发送消息function sendMessage() {var message = $("#message").val();// 发送消息到"/request/send",其中/request是服务器定义的前缀// 而/send则是@MessageMapping所配置的路径stompClient.send("/request/send", {}, message);}connect();
var noticeSocket = function () {// 连接服务器端点var s = new SockJS('/socket');//客户端var stompClient = Stomp.over(s);stompClient.connect({}, function () {console.log("notice socket connected !");// 订阅消息地址,这里的/sub是在配置里设置的sub前缀,/sub/chat是后端服务代码中@SendTo注解消息路由到的订阅路径中stompClient.subscribe('/sub/chat', function (data) {$('#receive').html(data.body);});});};noticeSocket();

后端服务代码

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;import javax.annotation.Resource;
import java.security.Principal;/*** @author */
@Controller
@RequestMapping("/device/ws")
@Api(tags = "WebsocketController")
public class WebsocketController {private final Logger logger = LoggerFactory.getLogger(WebsocketController.class);@MessageMapping("/send")@SendTo("/sub/chat")public String sendMessage(String value) {logger.info("发送消息内容:{}", value);return value;}/*** 测试发送广播消息的前端* @return*/@GetMapping("/test")public String test() {return "request";}/*** 测试接受广播消息的前端* @return*/@GetMapping("/user")public String user() {return "user";}
}

@MessageMapping注解的/send就是前端发送时路径的一部分,再加上服务前缀request,就是前端发送信息的完整路径/request/send.
@SendTo注解的路径是将要消息路由到的路径,正好是前端订阅的路径。
发送过来的消息可以在这里进行整理或处理后再转发出去

实现一对一发送

前端代码

发送信息的前端代码



websocket STOMP


websocket兼容STOMP测试11

跳转到消息接收页

stompClient.send 把信息发送到后端,
/requst 是服务端统一的前缀路径
/sendUser 是@MessageMaping的路径

接收信息的前端



websocket-stomp-receive





等待接收消息

解释:

// 订阅消息地址,stompClient.subscribe('/sub/admin/queue/customer', function (data) {console.log("接受到的消息:"+data)$('#receive').html(data.body);});

/sub/admin/queue/customer
/sub 是接收信息的订阅的前缀
/admin 是指定的user
/queue/customer 是转发信息的destination,目的地

后端服务代码


import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;import javax.annotation.Resource;
import java.security.Principal;/*** @author */
@Controller
@RequestMapping("/device/ws")
@Api(tags = "WebsocketController")
public class WebsocketController {private final Logger logger = LoggerFactory.getLogger(WebsocketController.class);@Resourceprivate SimpMessagingTemplate simpMessagingTemplate;@MessageMapping("/sendToUser")public void sendToUser(Principal principal, String body,String token) {
//        String srcUser = principal.getName();System.out.println("传入的token是:"+token);String[] args = body.split(": ");String desUser = args[0];String message = String.format("【%s】给你发来消息:%s", "mali", args[1]);// 发送到用户和监听地址simpMessagingTemplate.convertAndSendToUser(desUser, "/queue/customer", message);}/*** 测试发送指定用户的前端* @return*/@GetMapping("/sendUser")public String sendUser() {return "sendUser";}/*** 接受指定用户的前端* @return*/@GetMapping("/userId")public String userId() {return "userId";}
}
 @MessageMapping("/sendToUser")public void sendToUser(Principal principal, String body,String token) {
//        String srcUser = principal.getName();System.out.println("传入的token是:"+token);String[] args = body.split(": ");String desUser = args[0];String message = String.format("【%s】给你发来消息:%s", "mali", args[1]);// 发送到用户和监听地址simpMessagingTemplate.convertAndSendToUser(desUser, "/queue/customer", message);}

这个方法正是前端发送消息的路径/sendToUser,路由消息的时候使用simpMessageTemplate.convertAndToUser,destUser是前端传过来的,
/queue/customer也是用户订阅的目的地址,发送的消息是message

相关内容

热门资讯

贷款也“拼团” 银行抢单忙 购物能“拼团”,贷款也能! 近日,一场“拼团融资”的银企对接活动在省工业和信息化厅拉开帷幕。 “贷款...
逛花展、赶市集、嗨直播!202... 5月23日 “2026北京直播电商购物月” 在丰台区丽泽金融商务区·2026北京国际花展 正式拉开帷...
2026中关村毕业季|AI“吃... “上帝会掷骰子吗?” 在联想未来中心的“与智者同场”展区,一位海淀学子对着屏幕问道。 爱因斯坦微微前...
原创 今... 今日为5月23日,国际现货黄金价格在4500美元/盎司整数关口附近徘徊不前,日内最低触及4480美元...
三连亏后变为“无主”状态,农尚... 从吴亮手中接盘农尚环境(300536)不足三年后,林峰如今让出了公司控制权,上市公司进入“无主”状态...
55岁湖南女首富出手!豪掷13... 快科技5月24日消息,与马斯克、库克并肩而坐,刚参加完国宴的湖南女首富周群飞就买了家上市企业。 近日...
外资加仓A股,岂是跟风这么简单... 熬过忙碌的交易日,在周末安静时段,理清接下来布局方向。本篇为大家准备了5条要闻,涵盖市场动态、行业变...
原创 俄... 在全球能源的残酷牌桌上,手里攥着石油,腰杆子才能硬气。长期以来,中东的沙漠、俄罗斯的冰原、美国的页岩...
喜力啤酒有产品将涨价,华润啤酒... 来源:红星新闻 红星资本局5月22日消息,今日,红星资本局从雪花啤酒(厦门)有限公司、华润啤酒方面获...
原创 金... 心理预期调整刻不容缓,五月二十二日,黄金价格或将重现十五年前的历史性低迷。 近期若您密切关注着黄金市...
原创 马... 埃隆·马斯克如果能让SpaceX实现“科幻小说”级别的目标,他可能获得1万亿美元的收入。 埃隆·马斯...
涨涨涨!放开限制、可加杠杆!这... 韩国股市站在风口上! 据最新消息,为吸引更多海外资金进入股市,韩国政府计划放开限制,允许境外投资者直...
下周9家上会丨科创板首单IPO... IPO及再融资上会预告 据交易所官网审核动态信息,下周(5.25-5.29)IPO上会审核6家企业,...
富途、老虎市值蒸发1/4!或被... 来源:金融时报 5月22日,中国证监会宣布依法对Tiger Brokers (NZ) Limited...
马爸爸的好兄弟钱多多搞了杀猪盘... *此图由AI生成 作者| 史大郎&猫哥 来源| 是史大郎&大猫财经Pro 上周四,港股经纬天地大崩盘...
原创 壳... 编辑:XL 国际能源圈最近炸开了锅,壳牌这家百年石油巨头在2026年3月与委内瑞拉政府正式签署多项油...
存储热潮愈演愈烈!奖金拿到手软... 财联社5月24日讯(编辑 卞纯)在席卷全球的存储芯片热潮中,韩国“存储芯片双雄”SK海力士和三星无疑...
揽牌、合作、生态,跨境支付头部... 近日,国内头部跨境支付机构密集落地海外重要布局,一方面,连连数字、PingPong两家公司相继在中东...
原创 帮... 老铁们,周末好!我是帮主郑重。刚扫了一眼下周的财经日历,好家伙,事件一个接一个,堪称“消息面轰炸周”...
海南省住建厅与中国石化海南石油... 5月22日,中国石化海南石油分公司代表、党委书记李新强、总经理蔡文东一行赴海南省住建厅拜访交流。省住...