博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
spring 整合websoket(整理)
阅读量:6842 次
发布时间:2019-06-26

本文共 3948 字,大约阅读时间需要 13 分钟。

hot3.png

定义:

  • sockjs.js:  浏览器JavaScript库,它提供了一个类似于网络的对象。SockJS提供了一个连贯的、跨浏览器的Javascript API,它在浏览器和web服务器之间创建了一个低延迟、全双工、跨域通信通道。

  • STOMP:简单(流)文本定向消息协议,它提供了一个可互操作的连接格式,允许STOMP客户端与任意STOMP消息代理(Broker)进行交互。有点像TCP和HTTP之间的关系,在websocket的通信中,有了STOMP协议后,客户端和服务端能够以更友好的方式进行交流。如果没有提供第三方的STOMP代理,比如Rabbitmq等,那么使用的就是spring容器自己提供的STOMP代理。

关系:

能够使用sock.js建立websocket的客户端连接。websocket可以使用STOMP协议作为传输的协议。

样例代码如下:

  • 定义WebSocketMessageBrokerConfigurer,一般是继承自AbstractWebSocketMessageBrokerConfigurer:
@Configuration@EnableWebSocketMessageBroker  //在 WebSocket 上启用 STOMPpublic class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {    @Override    public void configureMessageBroker(MessageBrokerRegistry config) {        /**         * 启用了STOMP代理中继功能:并将其目的地前缀设置为 "/topic";         * spring就能知道 所有目的地前缀为"/topic" 的消息都会发送到STOMP代理中;         */        config.enableSimpleBroker("/topic", "/user");        /**         * 设置了应用的前缀为"app":所有目的地以"/app"打头的消息(发送消息url not连接url)         * 都会路由到带有@MessageMapping注解的方法中,而不会发布到代理队列或主题中;         */        config.setApplicationDestinationPrefixes("/app");    }    @Override    public void registerStompEndpoints(StompEndpointRegistry registry) {        registry.addEndpoint("/webSocket").setAllowedOrigins("*").withSockJS();    }}
  1. registerStompEndpoints:注册websocket的端点地址,也就是客户端连接的地址,在上面的配置中,客户端连接的地址是:
  2. setAllowedOrigins:上面的代码中表示是所有的ip地址都能够连接,也可以对固定的地址进行过滤。
  3. sockjs():提供对sockjs访问的支持。

websocket一般有两种应用场景:

  • 客户端订阅到服务端,这个时候服务端会处理一些客户端的信息,比如将客户端的信息注册到服务端的列表之中。
  • 服务端收到消息后进行推送到客户端。

上面的配置中:

  • /app:代表客户端直接发送给服务端的消息,不需要经过stomp消息代理,将由@MessageMapping的直接处理,并返回消息。
    例如:客户端发送的消息:
stompClient.send("/app/webSocket/updateDevice", {}, JSON.stringify(req));

/app/websockt/send将由下面的代码来进行处理:

@MessageMapping("/webSocket/send")    public void updateDevice(SimpMessageHeaderAccessor headerAccessor, String requestContent)        throws Exception {        SubscriptionMsg msg = JSON.parseObject(requestContent, SubscriptionMsg.class);        System.out.println(msg);    }

STOMP消息代理的配置如下:

config.enableSimpleBroker("/topic", "/user");

客户端使用stompClient.subscribe("/topic/theme"),将通过STOMP订阅在这个topic的主题.

  • 发送消息到单个/user通道:
@Override    public void configureMessageBroker(MessageBrokerRegistry registry) {//        registry.setPathMatcher(new AntPathMatcher("."));//可以已“.”来分割路径,看看类级别的@messageMapping和方法级别的@messageMapping         registry.enableSimpleBroker("/topic","/user");        registry.setUserDestinationPrefix("/user/");        registry.setApplicationDestinationPrefixes("/app");//走@messageMapping    }
@RequestMapping("/app")@Controllerpublic class WebSocketController {    @Resource    private SimpMessagingTemplate simpMessagingTemplate;     @MessageMapping("/hello")//  @SendTo("/topic/hello")//会把方法的返回值广播到指定主题(“主题”这个词并不合适)    public void toTopic(SocketMessageVo msg , String name) {        System.out.println(msg.getName()+","+msg.getMsg());        this.simpMessagingTemplate.convertAndSend("/topic/hello",msg.getName()+","+msg.getMsg());//      return "消息内容:"+ msg.getName()+"--"+msg.getMsg();    }     @MessageMapping("/message")//  @SendToUser("/message")//把返回值发到指定队列(“队列”实际不是队列,而是跟上面“主题”类似的东西,只是spring在SendTo的基础上加了用户的内容而已)    public void toUser(SocketMessageVo msg ) {        System.out.println(msg.getName()+","+msg.getMsg());        this.simpMessagingTemplate.convertAndSendToUser("123","/message",msg.getName()+msg.getMsg());    }     @RequestMapping("/sendMsg")    public void sendMsg(HttpSession session){        System.out.println("测试发送消息:随机消息" +session.getId());        this.simpMessagingTemplate.convertAndSendToUser("123","/message","后台具体用户消息");    }}

总结一下:

WebSocketConfig 中配置setApplicationDestinationPrefixes()的消息会被转发到WebSocketController 中 @MessageMapping 相应方法进行处理。@SendTo("/topic/message") 会把方法的返回值序列化为json串,然后发送到指定的主题,不用此注解,使用 simpMessagingTemplate.convertAndSend 效果相同;若为 @SendToUser("/message") 则为发送到指定的用户队列(实际队列名字为/user/用户名/原队列名),不用此注解,使用 simpMessagingTemplate.convertAndSendToUser() 效果相同;

参考文档:

转载于:https://my.oschina.net/u/2297579/blog/1924336

你可能感兴趣的文章