spring boot+vue实现stomp协议
创始人
2024-11-14 23:03:45
0

一、后端
1、安装依赖

             org.springframework.boot             spring-boot-starter-websocket          

2、定义消息实体类(根据特定业务来定义)

@Data @AllArgsConstructor public class ChatMessage {     String sender;     String message; } 

3、定义配置文件类

package com.example.stomptest.config;  import lombok.extern.slf4j.Slf4j; import org.springframework.context.annotation.Configuration; import org.springframework.messaging.Message; import org.springframework.messaging.MessageChannel; import org.springframework.messaging.simp.config.ChannelRegistration; import org.springframework.messaging.simp.config.MessageBrokerRegistry; 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.web.socket.config.annotation.EnableWebSocketMessageBroker; import org.springframework.web.socket.config.annotation.StompEndpointRegistry; import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;  @Configuration @EnableWebSocketMessageBroker @Slf4j public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {     /**      * 注册Stomp服务端点      * @param registry      */     @Override     public void registerStompEndpoints(StompEndpointRegistry registry) {         // addEndpoint 设置与客户端建立连接的url         registry.addEndpoint("/ws")                 // 设置允许跨域                 .setAllowedOriginPatterns("*")                 // 允许SocketJs使用,是为了防止某些浏览器客户端不支持websocket协议的降级策略                 .withSockJS();     }      /**      * 配置消息代理      */     @Override     public void configureMessageBroker(MessageBrokerRegistry registry) {         // 客户端发送消息的请求前缀         registry.setApplicationDestinationPrefixes("/app");          // 客户端订阅消息的请求前缀,topic一般用于广播推送,queue用于点对点推送         registry.enableSimpleBroker("/topic", "/queue");          // 服务端通知客户端的前缀,可以不设置,默认为user         registry.setUserDestinationPrefix("/user");     }      @Override     public void configureClientInboundChannel(ChannelRegistration registration) {         registration.interceptors(new ChannelInterceptor() {             @Override             public Message preSend(Message message, MessageChannel channel) { //                log.info("--websocket信息发送前--");                 StompHeaderAccessor accessor = MessageHeaderAccessor.getAccessor(message, StompHeaderAccessor.class);                 if (accessor != null) {                     // 判断是否是连接Command 如果是,需要获取token对象                     if (StompCommand.CONNECT.equals(accessor.getCommand())) {                         String token = accessor.getFirstNativeHeader("token");//下方可执行解析token逻辑                         log.info("toekn信息:"+token); //                        final String token = accessor.getFirstNativeHeader(Constant.HEADER_TOKEN); //                        if (!TokenUtil.validateToken(token)) { //                            return null; //                        } //                        final LoginUser user = TokenUtil.getUserFromToken(token); //                        UserUtil.setUser(user);                         // sendToUser 需要与这里的user获取的principal一样 //                        accessor.setUser(new SocketUser(user));                         accessor.setUser(() -> "test");                         log.info("websocket 连接成功");                     }                 }                 return message;             }         });     } }  

4、定义监视器

package com.example.stomptest.handle;  import com.example.stomptest.entity.ChatMessage; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.springframework.context.event.EventListener; import org.springframework.messaging.simp.SimpMessageSendingOperations; import org.springframework.messaging.simp.stomp.StompHeaderAccessor; import org.springframework.stereotype.Component; import org.springframework.web.socket.messaging.SessionConnectEvent; import org.springframework.web.socket.messaging.SessionDisconnectEvent;  @Component @Slf4j public class WebSocketEventListener {     @Resource     private SimpMessageSendingOperations messagingTemplate;      /**      * 连接建立事件      * @param event      */     @EventListener     public void handleWebSocketConnectListener(SessionConnectEvent event) {         log.info("建立一个新的连接");     }       @EventListener     public void handleWebSocketDisconnectListener(SessionDisconnectEvent event) {  //        StompHeaderAccessor headerAccessor = StompHeaderAccessor.wrap(event.getMessage()); // //        String username = (String) headerAccessor.getSessionAttributes().get("login");         log.info("用户断开连接");     } }  

5、定义控制器测试用

package com.example.stomptest.controller;   import com.example.stomptest.entity.ChatMessage; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.springframework.messaging.handler.annotation.DestinationVariable; import org.springframework.messaging.handler.annotation.MessageMapping; import org.springframework.messaging.handler.annotation.Payload; import org.springframework.messaging.handler.annotation.SendTo; import org.springframework.messaging.simp.SimpMessageHeaderAccessor; import org.springframework.messaging.simp.SimpMessagingTemplate; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController;  import java.security.Principal;  @RestController @Slf4j public class ChatController {     @Resource     private SimpMessagingTemplate messagingTemplate;       @MessageMapping("/sendToAll") //    @SendTo("/topic/notice")     public String sendToAll(String message) {         String result="服务端通知: " + message;         messagingTemplate.convertAndSend("/topic/notice",result);         return result;     }      /**      * 点对点发送消息      * 

* 模拟 张三 给 李四 发送消息场景 * @param username 接收消息的用户 * @param message 消息内容 */ @MessageMapping("/sendToUser/{username}") public void sendToUser(@DestinationVariable String username, String message) { String sender="1910"; String receiver = username; // 接收人 log.info("发送人:{}; 接收人:{}", sender, receiver); // 发送消息给指定用户 /user/{username}/queue/greeting messagingTemplate.convertAndSendToUser(receiver, "/queue/message", new ChatMessage(sender, message)); } }

二、前端
1、安装依赖

npm i stompjs -S  npm i sockjs-client -S 

2、测试代码

      

相关内容

热门资讯

绝活儿辅助!广西老友玩老是输怎... 绝活儿辅助!广西老友玩老是输怎么办(辅助挂)都是真的有辅助app(讲解有挂)在进入广西老友玩老是输怎...
法门辅助!福建13水插件(辅助... 法门辅助!福建13水插件(辅助挂)一贯是有辅助技巧(有挂技术)1、许多玩家不知道福建13水插件辅助怎...
办法辅助!潮友会app下载官方... 办法辅助!潮友会app下载官方辅助器(辅助挂)真是真的是有辅助app(有挂教程)该软件可以轻松地帮助...
妙招辅助!邯郸胡乐挂辅助(辅助... 妙招辅助!邯郸胡乐挂辅助(辅助挂)好像存在有辅助插件(有挂方略)1、上手简单,内置详细流程视频教学,...
教程书辅助!乐酷辅助(辅助挂)... 教程书辅助!乐酷辅助(辅助挂)其实存在有辅助脚本(有挂细节)乐酷辅助能透视中分为三种模型:乐酷辅助模...
学习辅助!决战卡五星辅助(辅助... 学习辅助!决战卡五星辅助(辅助挂)本来真的是有辅助软件(有人有挂)学习辅助!决战卡五星辅助(辅助挂)...
绝活辅助!边锋嘉兴麻将辅助器(... 绝活辅助!边锋嘉兴麻将辅助器(辅助挂)真是真的有辅助神器(新版有挂)1、边锋嘉兴麻将辅助器公共底牌简...
举措辅助!枫叶辅助器(辅助挂)... 举措辅助!枫叶辅助器(辅助挂)本来存在有辅助技巧(竟然有挂)1、下载好枫叶辅助器正确养号方法之后点击...
讲义辅助!点我达辅助(辅助挂)... 讲义辅助!点我达辅助(辅助挂)一直存在有辅助技巧(有人有挂)1、点我达辅助辅助器安装包、点我达辅助辅...
模块辅助!威信茶馆有挂的吗(辅... 模块辅助!威信茶馆有挂的吗(辅助挂)一直真的是有辅助脚本(揭秘有挂)1、玩家可以在威信茶馆有挂的吗线...