快速上手SpringBoot下即时通讯技术WebSocket
1.在pom.xml内引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
2. 编写私信处理器
@Slf4j
public class MessageHandler extends TextWebSocketHandler {
@Resource
private MessageDao messageDao;
@Resource
private StringRedisTemplate stringRedisTemplate;
private static final ObjectMapper MAPPER = new ObjectMapper();
private static final Map<Long, WebSocketSession> SESSIONS = new HashMap<>();
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
Long id = BaseContext.getUserId();
SESSIONS.put(id, session);
}
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
Long id = BaseContext.getUserId();
SESSIONS.remove(id);
}
@Override
protected void handleTextMessage(WebSocketSession session, TextMessage textMessage) throws Exception {
String path = session.getUri().getPath();
String[] flag = StringUtils.split(path, "/");
String key = LOGIN_TOKEN_KEY + flag[1];
Long id = Long.valueOf(stringRedisTemplate.opsForValue().get(key));
JsonNode jsonNode = MAPPER.readTree(textMessage.getPayload());
Long toId = jsonNode.get("toId").asLong();
String msg = jsonNode.get("msg").asText();
Message message = Message.builder()
.from(id)
.to(toId)
.msg(msg)
.build();
message = messageDao.saveMessage(message);
String messageJSON = JSONUtil.toJsonStr(message);
WebSocketSession toSession = SESSIONS.get(toId);
if (toSession != null && toSession.isOpen()) {
toSession.sendMessage(new TextMessage(messageJSON));
messageDao.updateMessageStatus(message.getId(), 0);
}
}
}
3.编写建立连接前的拦截器
public class MessageHandshakeInterceptor implements HandshakeInterceptor {
@Resource
private StringRedisTemplate stringRedisTemplate;
public MessageHandshakeInterceptor(){}
public MessageHandshakeInterceptor(StringRedisTemplate stringRedisTemplate){
this.stringRedisTemplate = stringRedisTemplate;
}
@Override
public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {
String path = request.getURI().getPath();
String[] flag = StringUtils.split(path, "/");
if (flag.length != 2){
response.setStatusCode(HttpStatus.UNAUTHORIZED);
return false;
}
String key = LOGIN_TOKEN_KEY + flag[1];
String id = stringRedisTemplate.opsForValue().get(key);
if (StringUtils.isEmpty(id)){
response.setStatusCode(HttpStatus.UNAUTHORIZED);
return false;
}
BaseContext.setMember(Long.valueOf(id));
return true;
}
@Override
public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception exception) {
}
}
4. 编写配置类
@Configuration
@EnableWebSocket
@Import(MessageHandler.class)
public class WebSocketConfig implements WebSocketConfigurer {
@Resource
private MessageHandler messageHandler;
@Resource
private StringRedisTemplate stringRedisTemplate;
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(this.messageHandler,"/ws/{token}")
.setAllowedOrigins("*")
.addInterceptors(new MessageHandshakeInterceptor(stringRedisTemplate));
}
}