第二篇,主要是使用socketjs,stomp模式的websocket简单实现。
第一篇的地址:springboot2.0+websocket集成【群发消息+单对单】
参考:
http://tech.lede.com/2017/03/08/qa/websocket+spring/
https://blog.csdn.net/mr_zhuqiang/article/details/46618197
继续上次的项目。如果对下面的代码有部分看不明白的,请到上一篇看看流程,或者到文末贴出项目的git地址。
1. 先从配置开始,WebStompConfig
代码中的注释基本能够解释清楚每行的意思了,这里就不再细说
完整代码
package com.example.websocketdemo1.stomp;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.ChannelRegistration;
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;
/**
* EnableWebSocketMessageBroker 注解表明: 这个配置类不仅配置了 WebSocket,还配置了基于代理的 STOMP 消息;
* registerStompEndpoints() 方法:添加一个服务端点,来接收客户端的连接。将 “/chat” 路径注册为 STOMP 端点。这个路径与之前发送和接收消息的目的路径有所不同, 这是一个端点,客户端在订阅或发布消息到目的地址前,要连接该端点,即用户发送请求 :url=’/127.0.0.1:8080/chat’ 与 STOMP server 进行连接,之后再转发到订阅url;
* configureMessageBroker() 方法:配置了一个 简单的消息代理,通俗一点讲就是设置消息连接请求的各种规范信息。
*
* @author linyun
* @date 2018/9/13 下午5:15
*/
@Configuration
@EnableWebSocketMessageBroker
public class WebStompConfig implements WebSocketMessageBrokerConfigurer {
@Autowired
private WebSocketHandleInterceptor interceptor;
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
//添加一个/chat端点,客户端就可以通过这个端点来进行连接;withSockJS作用是添加SockJS支持
registry.addEndpoint("/chat").setAllowedOrigins("*").withSockJS();
}
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
//定义了两个客户端订阅地址的前缀信息,也就是客户端接收服务端发送消息的前缀信息
registry.enableSimpleBroker("/message", "/notice");
//定义了服务端接收地址的前缀,也即客户端给服务端发消息的地址前缀
registry.setApplicationDestinationPrefixes("/app");
}
@Override
public void configureClientInboundChannel(ChannelRegistration registration) {
//注册了一个接受客户端消息通道拦截器
registration.interceptors(interceptor);
}
}
2. 用户信息注册,WebSocketHandleInterceptor
上一篇里面,用户信息我们是直接存储到session中,然后再通过握手的时候,将用户信息存入WebSocketSession。
这次使用stomp的模式也存在一个单对单的发送消息,就需要知道对方是谁,所以也要注册一下用户信息。
完整的代码
package com.example.websocketdemo1.stomp;
import com.sun.security.auth.UserPrincipal;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.simp.stomp.StompCommand;
import org.springframework.messaging.simp.stomp.StompHeaderAccessor;
import org.springframework.messaging.support.ChannelInterceptor;
import org.springframework.messaging.support.MessageHeaderAccessor;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import java.security.Principal;
/**
* @author linyun
* @date 2018/9/13 下午5:57
*/
@Component
public class WebSocketHandleInterceptor implements ChannelInterceptor {
/**
* 绑定user到websocket conn上
* @param message
* @param channel
* @return
*/
@Override
public Message<?> preSend(Message<?> message, MessageChannel channel) {
StompHeaderAccessor accessor = MessageHeaderAccessor.getAccessor(message, StompHeaderAccessor.class);
if (StompCommand.CONNECT.equals(accessor.getCommand())) {
String username = accessor.getFirstNativeHeader("username"