参考文章:英文:https://www.callicoder.com/spring-boot-websocket-chat-example/
中文:https://mp.weixin.qq.com/s?__biz=MzI4Njg5MDA5NA==&mid=2247485578&idx=1&sn=eac39f010b8c2be949e0daae770fd7ae&chksm=ebd7498bdca0c09d2dad0af154f53d2aa2c9a0cce6602d1814346257f74583ab5b7fbd2b7eb9&token=1948873548&lang=zh_CN#rd
简单的来说可以理解为一个平常的http请求,只不过参数的返回时,会通知所有监听这一信道的页面以调用回调函数的形式返回。可以也就是说,当我去请求一个后端接口时,所有监听这一信道的页面,都会被调起回调函数。其实就跟mq一样。
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.*;
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
// 这个就是注册一个websocket端口,客户端利用这个连接到服务
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/ws").withSockJS();
}
// 定义消息处理方法的前缀,以及消息路由的前缀
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.setApplicationDestinationPrefixes("/app");
registry.enableSimpleBroker("/topic");
}
}
定义实体类:
@Data
public class ChatMessage {
private MessageType type;
private String content;
private String sender;
public enum MessageType {
CHAT, // 消息
JOIN, // 加入
LEAVE // 离开
}
}
关键的消息方法:
@Controller
public class ChatController {
@MessageMapping("/chat.sendMessage")
@SendTo("/topic/public") //这里可以利用Spring中的SimpMessagingTemplate的convertAndSendToUser方法,实现私聊功能(就是换一个私人的信道)
public ChatMessage sendMessage(@Payload ChatMessage chatMessage) {
return chatMessage;
}
@MessageMapping("/chat.addUser")
@SendTo("/topic/public")
public ChatMessage addUser(@Payload ChatMessage chatMessage,
SimpMessageHeaderAccessor headerAccessor) {
// Add username in web socket session
headerAccessor.getSessionAttributes().put("username", chatMessage.getSender());
return chatMessage;
}
}
然后就是前端的js代码:
需要先导入包
<script src="https://cdn.bootcss.com/sockjs-client/1.1.4/sockjs.min.js"></script>
<script src="https://cdn.bootcss.com/stomp.js/2.3.3/stomp.min.js"></script>
function connect() {
var socket = new SockJS('/ws'); // 这个就是先前在后端的websocket端口
stompClient = Stomp.over(socket);
stompClient.connect({}, onConnected, onError);
}
}
function onConnected() {
// 这里就是监听的信道,想要实现私聊功能,可以动态设置监听信道
stompClient.subscribe('/topic/public', onMessageReceived);
}
function onError(error) {
connectingElement.textContent = 'Could not connect to WebSocket server. Please refresh this page to try again!';
connectingElement.style.color = 'red';
}
function sendMessage(event) {
var messageContent = messageInput.value.trim();
if(messageContent && stompClient) {
var chatMessage = {
sender: username,
content: messageInput.value,
type: 'CHAT'
};
stompClient.send("/app/chat.sendMessage", {}, JSON.stringify(chatMessage));//这里就是控制器的Mapping
messageInput.value = '';
}
event.preventDefault();
}
function onMessageReceived(payload) {
var message = JSON.parse(payload.body);
if(message.type === 'JOIN') {
xxxx前端显示
} else if (message.type === 'LEAVE') {
xxxx前端显示
} else {
xxxx前端显示
}
}
原文的demo地址:https://github.com/qqxx6661/springboot-websocket-demo
还有一个推荐的仓库地址(功能以及效果都非常不错):https://github.com/anlingyi/xechat