(本项目用的maven为IDEA创建springboot项目时常用的maven依赖)
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-test
test
org.junit.vintage
junit-vintage-engine
org.springframework
spring-messaging
5.2.12.RELEASE
org.springframework
spring-websocket
5.2.12.RELEASE
1.先创建websocket的配置类 WebSocketConfig
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.AbstractWebSocketMessageBrokerConfigurer;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
@Override
public void registerStompEndpoints(StompEndpointRegistry stompEndpointRegistry) {
/*
* 路径"/webSocket"被注册为STOMP端点,对外暴露(允许跨域),客户端通过该路径接入WebSocket服务
* setAllowedOrigins("192.168.1.1") 这里添加的是允许访问的站点 我这里写成了*,就是允许所有的客户端接入站点【不安全】
*
* html中js创建socket对象时候 用的就是这里的"/webSocket": var socket = new SockJS('/webSocket');
*/
stompEndpointRegistry.addEndpoint("/webSocket").setAllowedOrigins("*").withSockJS();
}
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
/*
* 用户可以订阅来自"/topic"和"/user"的消息,
* 在Controller中,可通过@SendTo注解指明发送目标,这样服务器就可以将消息发送到 订阅相关消息的客户端 【所有人或者某个人】
*
* 在本例子中,使用topic来达到群发效果,使用user进行一对一发送
*
* 客户端只可以订阅这两个前缀的主题
*/
registry.enableSimpleBroker("/topic", "/user");
/*
* 客户端发送过来的消息,需要以"/topic"为前缀,再经过Broker转发给响应的Controller
* 订阅主题:'/topic/get/broadcast'
* 推送方式:1.@SendTo("/topic/get/broadcast")
* 2.ResponseMessage responseMessage = new ResponseMessage("hello everyone!");
*/
registry.setApplicationDestinationPrefixes("/topic");
/*
* 一对一发送的前缀
* 订阅主题(html):'/user/huoLaoShu/get/somebodyMessage'
* 推送方式:1、@SendToUser("/get/somebodyMessage")
* 2、messagingTemplate.convertAndSendToUser(userName, "/get/somebodyMessage", responseMessage);;
*/
registry.setUserDestinationPrefix("/user");
}
}
2.然后创建springboot项目 控制层 WsController 【类中引用了两个我自定义的bean:RequestMessage 和 ResponseMessage】
package org.xlx.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.messaging.simp.annotation.SendToUser;
import org.springframework.messaging.simp.stomp.StompHeaderAccessor;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestBody;
import org.xlx.websocket.bean.RequestMessage;
import org.xlx.websocket.bean.ResponseMessage;
@Controller
@CrossOrigin
public class WsController {
/*
* 使用restful风格
*/
private final SimpMessagingTemplate messagingTemplate;
/*
* 实例化Controller的时候,注入SimpMessagingTemplate
*/
@Autowired
public WsController(SimpMessagingTemplate messagingTemplate) {
this.messagingTemplate = messagingTemplate;
}
/**
* 广播
* @param message
* @return
*/
@MessageMapping("/send/broadcast") //前台发送广播消息的时候, 地址为 /topic/send/broadcast
@SendTo("/topic/get/broadcast") //前台订阅这个消息的时候 为 /topic/get/broadcast
// 因为我html里传过来的值为 {"name": "发送内容"} 所以接收的对象可以直接转成我自己定义的bean RequestMessage
// 【里面只有一个name属性】 后续可以根据自己的业务逻辑修改自己需要的类
public ResponseMessage broadcast(@RequestBody RequestMessage message, StompHeaderAccessor headerAccessor){
//TODO 此处可以添加自己的业务逻辑
// 将 message.getName() 通过广播发送给所有订阅了广播的 在线客户端
ResponseMessage responseMessage = new ResponseMessage(message.getName());
return responseMessage;
}
/**
* 发送私聊
* @param message
* @param headerAccessor
* @return
*/
@MessageMapping("/send/somebody") //前台发送私聊消息的时候, 地址为 /topic/send/somebody 例如:stompClient.send("/topic/send/somebody", {"username": "xuelongxin"}, JSON.stringify({"data": message}));
@SendToUser("/get/somebodyMessage") //前台订阅这个私聊消息的时候 为 /user/{userName}/get/somebodyMessage 例如: stompClient.subscribe('/user/xuelongxin/get/somebodyMessage', function (response) { 处理response })
public ResponseMessage sendSomebody(@RequestBody RequestMessage message,StompHeaderAccessor headerAccessor) {
//获取{"username": "huolaoshu"} 中的huolaoshu 确定私聊是给谁发的
// 这里 headerAccessor.getNativeHeader("username") 的值是 :[huolaoshu]
// 至于为啥会有个中括号 我也不清楚
String userName = headerAccessor.getNativeHeader("username").toString().replace("[","").replace("]","");
//把消息放到responseMessage 后定向发送 给 huolaoshu
ResponseMessage responseMessage = new ResponseMessage(message.getName());
messagingTemplate.convertAndSendToUser(userName, "/get/somebodyMessage", responseMessage);
return responseMessage;
}
}
3.两个自定义类:
public class RequestMessage {
private String name;
public String getName() {
return name;
}
}
public class ResponseMessage {
private String responseMessage;
public ResponseMessage(String responseMessage) {
this.responseMessage = responseMessage;
}
public String getResponseMessage() {
return responseMessage;
}
}
4.接下来是html+js文件
(1)guangbo.html
广播式WebSocket
(2)siliao.html
广播式WebSocket
5.两个html文件均引用了两个js文件 【sockjs.min.js和stomp.min.js】因为这两个js文件为第三方提供的库,太长,这里我提供下载地址:sockjs.min.js+stomp.min.js-Javascript文档类资源-CSDN下载sockjs.min.js+stomp.min.jshtml+js实现websocket的第更多下载资源、学习资料请访问CSDN下载频道.https://download.csdn.net/download/q18792880831/85547431。
6.下面附上项目 目录
7.实现的简单效果:
【广播】
【私聊】
8.各种解释已经写在代码注释里了,这里主要是实现了 用springboot作为后台,html+js为前台,实现简单的广播 和 私聊 功能,私聊这里我只是发送给了我自己 大家可以试试 多注册几个不同的用户【最简单的就是再新建几个siliao.html 然后修改里面的
stompClient.subscribe('/user/huolaoshu/get/somebodyMessage', function (response) {xxxxxx}
huolaoshu 然后只私发给huolaoshu 看看其他人是否能收到消息】大家可以多做尝试 ,如果对以上代码有任何疑问的,欢迎在评论区留言。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)