Spring Boot整合WebSocket 消息点对点发送
Spring Boot整合WebSocket 消息群发
添加依赖:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency>
配置Spring Security:
对Spring Security进行配置,添加两个用户,同时配置所有地址都认证后才能访问
@Configuration public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Bean PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication() .withUser("admin") .password("$2a$10$RMuFXGQ5AtH4wOvkUqyvuecpqUSeoxZYqilXzbz50dceRsga.WYiq") .roles("admin") .and() .withUser("sang") .password("$2a$10$RMuFXGQ5AtH4wOvkUqyvuecpqUSeoxZYqilXzbz50dceRsga.WYiq") .roles("user"); } @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .anyRequest().authenticated() .and() .formLogin().permitAll(); } }
改造WebSocket配置:
@Configuration @EnableWebSocketMessageBroker // 开启WebSocket消息代理 public class WebSocketConfig implements WebSocketMessageBrokerConfigurer { @Override public void configureMessageBroker(MessageBrokerRegistry config) { /* * 表示设置消息代理的前缀,即如果消息的前缀是“/topic”,就会将消息转发给消息代理(broker),再由消息代理将消息广播给当前连接的客户端。 */ config.enableSimpleBroker("/topic", "/queue"); /* * 表示配置一个或多个前缀,通过这些前缀过滤出需要被注解方法处理的消息 * 例如,前缀为“/app”的destination可以通过@MessageMapping注解的方法处理, * 而其他destination(例如“/ topic”“/ queue”)将被直接交给broker处理。 */ config.setApplicationDestinationPrefixes("/app"); } @Override public void registerStompEndpoints(StompEndpointRegistry registry) { /* * 表示定义一个前缀为“/chat”的endPoint,并开启sockjs支持, * sockjs可以解决浏览器对WebSocket的兼容性问题, * 客户端将通过这里配置的URL来建立WebSocket连接。 */ registry.addEndpoint("/chat").withSockJS(); } }
这里的修改是在config.enableSimpleBroker("/topic");方法的基础上又增加了一个broker前缀“/queue”,方便对群发消息和点对点消息进行管理。
配置Controller:
对WebSocket的Controller进行改造
@Controller public class GreetingController { @Autowired SimpMessagingTemplate messagingTemplate; @MessageMapping("/hello") // 用来接收“/app/hello”路径发送来的消息 在注解方法中对消息进行处理后,再将消息转发到@SendTo定义的路径上 @SendTo("/topic/greetings") // @SendTo路径是一个前缀为“/topic”的路径,因此该消息将被交给消息代理broker,再由broker进行广播。 public Message greeting(Message message) { return message; } /** * 点对点的消息发送 * * @param principal 用来获取当前登录用户的信息 * @param chat 客户端发送来的消息 */ @MessageMapping("/chat") // 注解表示来自“/app/chat”路径的消息将被chat方法处理 public void chat(Principal principal, Chat chat) { String from = principal.getName(); // 首先获取当前用户的用户名 chat.setFrom(from); // 设置给chat对象的from属性 /* * 再将消息发送出去,发送的目标用户就是chat对象的to属性值 * 消息发送使用的方法是convertAndSendToUser,该方法内部调用了convertAndSend方法,并对消息路径做了处理 * chat是一个普通的JavaBean,to属性表示消息的目标用户,from表示消息从哪里来,content则是消息的主体内容 */ messagingTemplate.convertAndSendToUser(chat.getTo(), "/queue/chat", chat); } }
创建在线聊天页面:
在resources/static目录下创建onlinechat.html页面作为在线聊天页面
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>单聊</title> <script src="/webjars/jquery/jquery.min.js"></script> <script src="/webjars/sockjs-client/sockjs.min.js"></script> <script src="/webjars/stomp-websocket/stomp.min.js"></script> <script src="/chat.js"></script> </head> <body> <div id="chat"> <div id="chatsContent"> </div> <div> 请输入聊天内容: <input type="text" id="content" placeholder="聊天内容"> 目标用户: <input type="text" id="to" placeholder="目标用户"> <button id="send" type="button">发送</button> </div> </div> </body> </html>
这个页面和chat.html页面基本类似,不同的是,为了演示方便,这里需要用户手动输入目标用户名。另外,还有一个chat.js文件
var stompClient = null; function connect() { var socket = new SockJS('/chat'); stompClient = Stomp.over(socket); stompClient.connect({}, function (frame) { // 连接成功后,订阅的地址为“/user/queue/chat”,该地址比服务端配置的地址多了“/user”前缀,这是因为SimpMessagingTemplate类中自动添加了路径前缀。 stompClient.subscribe('/user/queue/chat', function (chat) { showGreeting(JSON.parse(chat.body)); }); }); } function sendMsg() { // 聊天消息发送路径为“/app/chat” stompClient.send("/app/chat", {}, JSON.stringify({ 'content': $("#content").val(), 'to': $("#to").val() // 发送的消息内容中有一个to字段,该字段用来描述消息的目标用户 })); } function showGreeting(message) { $("#chatsContent") .append("<div>" + message.from + ":" + message.content + "</div>"); } $(function () { connect(); $("#send").click(function () { sendMsg(); }); });
测试:
接下来启动Spring Boot项目进行测试,在浏览器中输入http://localhost:8081/onlinechat.html
文章来源: Spring Boot+Vue全栈开发实战 - 11.3 Spring Boot整合WebSocket