mirror of
https://gitee.com/yudaocode/SpringBoot-Labs.git
synced 2026-09-03 05:53:54 +08:00
增加 spring websocket stomp 示例
This commit is contained in:
31
lab-25/lab-websocket-25-03/pom.xml
Normal file
31
lab-25/lab-websocket-25-03/pom.xml
Normal file
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.1.10.RELEASE</version>
|
||||
<relativePath/> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>lab-websocket-25-03</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<!-- 实现对 WebSocket 相关依赖的引入,方便~ -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-websocket</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 引入 Fastjson ,实现对 JSON 的序列化,因为后续我们会使用它解析消息 -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>fastjson</artifactId>
|
||||
<version>1.2.62</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,13 @@
|
||||
package cn.iocoder.springboot.lab25.springwebsocket;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class Application {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(Application.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package cn.iocoder.springboot.lab25.springwebsocket.config;
|
||||
|
||||
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;
|
||||
|
||||
@Configuration
|
||||
@EnableWebSocketMessageBroker // 开启 Spring WebSocket 对 Stomp 的支持
|
||||
public class WebSocketConfiguration implements WebSocketMessageBrokerConfigurer {
|
||||
|
||||
@Override
|
||||
public void configureMessageBroker(MessageBrokerRegistry registry) {
|
||||
registry.enableSimpleBroker("/topic");
|
||||
registry.setApplicationDestinationPrefixes("/app");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerStompEndpoints(StompEndpointRegistry registry) {
|
||||
// registry.addEndpoint("/send_to_all")
|
||||
// .setAllowedOrigins("*")
|
||||
// .withSockJS();
|
||||
registry.addEndpoint("/")
|
||||
.setAllowedOrigins("*")
|
||||
.withSockJS();
|
||||
|
||||
// RequestUpgradeStrategy upgradeStrategy = new TomcatRequestUpgradeStrategy();
|
||||
// registry.addEndpoint("/")
|
||||
// .setHandshakeHandler(new DefaultHandshakeHandler(upgradeStrategy))
|
||||
// .setAllowedOrigins("*");
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
|
||||
// registry.addHandler(this.webSocketHandler(), "/") // 配置处理器
|
||||
// .addInterceptors(new DemoWebSocketShakeInterceptor()) // 配置拦截器
|
||||
// .setAllowedOrigins("*"); // 解决跨域问题
|
||||
// }
|
||||
|
||||
// @Bean
|
||||
// public DemoWebSocketHandler webSocketHandler() {
|
||||
// return new DemoWebSocketHandler();
|
||||
// }
|
||||
|
||||
// @Bean
|
||||
// public DemoWebSocketShakeInterceptor webSocketShakeInterceptor() {
|
||||
// return new DemoWebSocketShakeInterceptor();
|
||||
// }
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package cn.iocoder.springboot.lab25.springwebsocket.controller;
|
||||
|
||||
import cn.iocoder.springboot.lab25.springwebsocket.message.SendToAllRequest;
|
||||
import cn.iocoder.springboot.lab25.springwebsocket.message.SendToUserRequest;
|
||||
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.stereotype.Controller;
|
||||
|
||||
@Controller
|
||||
public class SendController {
|
||||
|
||||
private Logger logger = LoggerFactory.getLogger(getClass());
|
||||
|
||||
@MessageMapping("/send_to_all")
|
||||
@SendTo(value = "/topic/send_to_all")
|
||||
public SendToUserRequest sendToAll(SendToAllRequest message) {
|
||||
logger.info("[sendToAll][SendToAllRequest({})]", message);
|
||||
// // 创建转发的消息
|
||||
// SendToUserRequest sendToUserRequest = new SendToUserRequest().setMsgId(message.getMsgId())
|
||||
// .setContent(message.getContent());
|
||||
// // 广播发送
|
||||
// WebSocketUtil.broadcast(SendToUserRequest.TYPE, sendToUserRequest);
|
||||
|
||||
// 这里,假装直接成功
|
||||
// return new SendResponse().setMsgId(message.getMsgId()).setCode(0);
|
||||
return new SendToUserRequest().setMsgId(message.getMsgId())
|
||||
.setContent(message.getContent());
|
||||
}
|
||||
|
||||
// @SubscribeMapping("/topic/send_to_all")
|
||||
// public void subSendToAll(SendToUserRequest message) {
|
||||
// logger.info("[subSendToAll][SendToUserRequest({})]", message);
|
||||
// }
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package cn.iocoder.springboot.lab25.springwebsocket.message;
|
||||
|
||||
/**
|
||||
* 用户认证请求
|
||||
*/
|
||||
public class AuthRequest implements Message {
|
||||
|
||||
public static final String TYPE = "AUTH_REQUEST";
|
||||
|
||||
/**
|
||||
* 认证 Token
|
||||
*/
|
||||
private String accessToken;
|
||||
|
||||
public String getAccessToken() {
|
||||
return accessToken;
|
||||
}
|
||||
|
||||
public AuthRequest setAccessToken(String accessToken) {
|
||||
this.accessToken = accessToken;
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package cn.iocoder.springboot.lab25.springwebsocket.message;
|
||||
|
||||
/**
|
||||
* 用户认证响应
|
||||
*/
|
||||
public class AuthResponse implements Message {
|
||||
|
||||
public static final String TYPE = "AUTH_RESPONSE";
|
||||
|
||||
/**
|
||||
* 响应状态码
|
||||
*/
|
||||
private Integer code;
|
||||
/**
|
||||
* 响应提示
|
||||
*/
|
||||
private String message;
|
||||
|
||||
public Integer getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public AuthResponse setCode(Integer code) {
|
||||
this.code = code;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public AuthResponse setMessage(String message) {
|
||||
this.message = message;
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package cn.iocoder.springboot.lab25.springwebsocket.message;
|
||||
|
||||
/**
|
||||
* 基础消息体
|
||||
*/
|
||||
public interface Message {
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package cn.iocoder.springboot.lab25.springwebsocket.message;
|
||||
|
||||
/**
|
||||
* 发送消息响应结果的 Message
|
||||
*/
|
||||
public class SendResponse implements Message {
|
||||
|
||||
public static final String TYPE = "SEND_RESPONSE";
|
||||
|
||||
/**
|
||||
* 消息编号
|
||||
*/
|
||||
private String msgId;
|
||||
/**
|
||||
* 响应状态码
|
||||
*/
|
||||
private Integer code;
|
||||
/**
|
||||
* 响应提示
|
||||
*/
|
||||
private String message;
|
||||
|
||||
public String getMsgId() {
|
||||
return msgId;
|
||||
}
|
||||
|
||||
public SendResponse setMsgId(String msgId) {
|
||||
this.msgId = msgId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Integer getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public SendResponse setCode(Integer code) {
|
||||
this.code = code;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public SendResponse setMessage(String message) {
|
||||
this.message = message;
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package cn.iocoder.springboot.lab25.springwebsocket.message;
|
||||
|
||||
/**
|
||||
* 发送给所有人的群聊消息的 Message
|
||||
*/
|
||||
public class SendToAllRequest implements Message {
|
||||
|
||||
public static final String TYPE = "SEND_TO_ALL_REQUEST";
|
||||
|
||||
/**
|
||||
* 消息编号
|
||||
*/
|
||||
private String msgId;
|
||||
/**
|
||||
* 内容
|
||||
*/
|
||||
private String content;
|
||||
|
||||
public String getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
public SendToAllRequest setContent(String content) {
|
||||
this.content = content;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getMsgId() {
|
||||
return msgId;
|
||||
}
|
||||
|
||||
public SendToAllRequest setMsgId(String msgId) {
|
||||
this.msgId = msgId;
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package cn.iocoder.springboot.lab25.springwebsocket.message;
|
||||
|
||||
/**
|
||||
* 发送给指定人的私聊消息的 Message
|
||||
*/
|
||||
public class SendToOneRequest implements Message {
|
||||
|
||||
public static final String TYPE = "SEND_TO_ONE_REQUEST";
|
||||
|
||||
/**
|
||||
* 发送给的用户
|
||||
*/
|
||||
private String toUser;
|
||||
/**
|
||||
* 消息编号
|
||||
*/
|
||||
private String msgId;
|
||||
/**
|
||||
* 内容
|
||||
*/
|
||||
private String content;
|
||||
|
||||
public String getToUser() {
|
||||
return toUser;
|
||||
}
|
||||
|
||||
public SendToOneRequest setToUser(String toUser) {
|
||||
this.toUser = toUser;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getMsgId() {
|
||||
return msgId;
|
||||
}
|
||||
|
||||
public SendToOneRequest setMsgId(String msgId) {
|
||||
this.msgId = msgId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
public SendToOneRequest setContent(String content) {
|
||||
this.content = content;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package cn.iocoder.springboot.lab25.springwebsocket.message;
|
||||
|
||||
/**
|
||||
* 发送消息给一个用户的 Message
|
||||
*/
|
||||
public class SendToUserRequest implements Message {
|
||||
|
||||
public static final String TYPE = "SEND_TO_USER_REQUEST";
|
||||
|
||||
/**
|
||||
* 消息编号
|
||||
*/
|
||||
private String msgId;
|
||||
/**
|
||||
* 内容
|
||||
*/
|
||||
private String content;
|
||||
|
||||
public String getMsgId() {
|
||||
return msgId;
|
||||
}
|
||||
|
||||
public SendToUserRequest setMsgId(String msgId) {
|
||||
this.msgId = msgId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
public SendToUserRequest setContent(String content) {
|
||||
this.content = content;
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package cn.iocoder.springboot.lab25.springwebsocket.message;
|
||||
|
||||
/**
|
||||
* 用户加入群聊的通知 Message
|
||||
*/
|
||||
public class UserJoinNoticeRequest implements Message {
|
||||
|
||||
public static final String TYPE = "USER_JOIN_NOTICE_REQUEST";
|
||||
|
||||
/**
|
||||
* 昵称
|
||||
*/
|
||||
private String nickname;
|
||||
|
||||
public String getNickname() {
|
||||
return nickname;
|
||||
}
|
||||
|
||||
public UserJoinNoticeRequest setNickname(String nickname) {
|
||||
this.nickname = nickname;
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package cn.iocoder.springboot.lab25.springwebsocket;
|
||||
|
||||
import cn.iocoder.springboot.lab25.springwebsocket.message.SendToAllRequest;
|
||||
import org.springframework.messaging.converter.MappingJackson2MessageConverter;
|
||||
import org.springframework.messaging.simp.stomp.StompCommand;
|
||||
import org.springframework.messaging.simp.stomp.StompHeaders;
|
||||
import org.springframework.messaging.simp.stomp.StompSession;
|
||||
import org.springframework.messaging.simp.stomp.StompSessionHandler;
|
||||
import org.springframework.web.socket.client.WebSocketClient;
|
||||
import org.springframework.web.socket.client.standard.StandardWebSocketClient;
|
||||
import org.springframework.web.socket.messaging.WebSocketStompClient;
|
||||
import org.springframework.web.socket.sockjs.client.SockJsClient;
|
||||
import org.springframework.web.socket.sockjs.client.Transport;
|
||||
import org.springframework.web.socket.sockjs.client.WebSocketTransport;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Scanner;
|
||||
import java.util.UUID;
|
||||
|
||||
public class Main {
|
||||
|
||||
public static void main(String[] args) {
|
||||
List<Transport> transports = new ArrayList<>(1);
|
||||
transports.add(new WebSocketTransport( new StandardWebSocketClient()) );
|
||||
WebSocketClient transport = new SockJsClient(transports); // TODO 芋艿,参考 https://codeday.me/bug/20190115/521240.html 文章
|
||||
// WebSocketClient client = new StandardWebSocketClient();
|
||||
|
||||
WebSocketStompClient stompClient = new WebSocketStompClient(transport);
|
||||
stompClient.setMessageConverter(new MappingJackson2MessageConverter());
|
||||
|
||||
StompSessionHandler sessionHandler = new StompSessionHandler() {
|
||||
|
||||
@Override
|
||||
public void afterConnected(StompSession stompSession, StompHeaders stompHeaders) {
|
||||
// stompSession.subscribe("/topic/send_to_all", this);
|
||||
stompSession.send("/app/send_to_all", new SendToAllRequest().setMsgId(UUID.randomUUID().toString())
|
||||
.setContent("测试消息"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleException(StompSession stompSession, StompCommand stompCommand, StompHeaders stompHeaders, byte[] bytes, Throwable throwable) {
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleTransportError(StompSession stompSession, Throwable throwable) {
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type getPayloadType(StompHeaders stompHeaders) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleFrame(StompHeaders stompHeaders, Object o) {
|
||||
System.out.println();
|
||||
}
|
||||
};
|
||||
|
||||
stompClient.connect("ws://127.0.0.1:8080/", sessionHandler);
|
||||
|
||||
new Scanner(System.in).nextLine(); // Don't close immediately.
|
||||
}
|
||||
|
||||
}
|
||||
Binary file not shown.
@@ -14,6 +14,7 @@
|
||||
<modules>
|
||||
<module>lab-websocket-25-01</module>
|
||||
<module>lab-websocket-25-02</module>
|
||||
<module>lab-websocket-25-03</module>
|
||||
</modules>
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user