Spring Boot 集成 websocket,使用RabbitMQ做为消息代理

 

Spring Boot 集成 websocket,使用RabbitMQ做为消息代理

<!-- rabbitmq -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
        </dependency>
        <!-- Stomp协议中使用RabbitMQ作为消息代理,所以还需要加入以下三个依赖 -->
        <dependency>
            <groupId>io.projectreactor</groupId>
            <artifactId>reactor-core</artifactId>
            <version>2.0.8.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>io.projectreactor</groupId>
            <artifactId>reactor-net</artifactId>
            <version>2.0.8.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>io.netty</groupId>
            <artifactId>netty-all</artifactId>
            <version>4.1.6.Final</version>
        </dependency>
        <!-- Stomp协议中使用RabbitMQ作为消息代理,三个依赖结束 -->


        
        
        
4.1. /exchange/exchangename/[routing_key]
通过交换机订阅/发布消息,交换机需要手动创建,参数说明 
a. /exchange:固定值 
b. exchangename:交换机名称 
c. [routing_key]:路由键,可选

.2. /queue/queuename
使用默认交换机订阅/发布消息,默认由stomp自动创建一个持久化队列,参数说明 
a. /queue:固定值 
b. queuename:自动创建一个持久化队列

对于接收者端,订阅队列queuename的消息 
对于接收者端,向queuename发送消息 
[对于 SEND frame,destination 只会在第一次发送消息的时候会定义的共享 queue]


4.3. /amq/queue/queuename
和上文的”/queue/queuename”相似,两者的区别是 
a. 与/queue/queuename的区别在于队列不由stomp自动进行创建,队列不存在失败

这种情况下无论是发送者还是接收者都不会产生队列。 但如果该队列不存在,接收者会报错。

4.4. /topic/routing_key
通过amq.topic交换机订阅/发布消息,订阅时默认创建一个临时队列,通过routing_key与topic进行绑定 
a. /topic:固定前缀 
b. routing_key:路由键

对于发送者端,会创建出自动删除的、非持久的队列并根据 routing_key路由键绑定到 amq.topic 交换机 上,同时实现对该队列的订阅。 
对于发送者端,消息会被发送到 amq.topic 交换机中。


@SendTo:会将接收到的消息发送到指定的路由目的地,所有订阅该消息的用户都能收到,属于广播。 
@SendToUser:消息目的地有UserDestinationMessageHandler来处理,会将消息路由到发送者对应的目的地, 此外该注解还有个broadcast属性,表明是否广播。
就是当有同一个用户登录多个session时,是否都能收到。取值true/false.

后台,控制层

	    //单独发, 一对一聊天
		@MessageMapping("/aloneRequestStomp") // 浏览器发送请求通过@messageMapping 映射/welcome 这个地址。
		//@SendTo("/alone/getResponse") // 服务器端会将消息广播给所有订阅/mass/getResponse这个路径的用户。
		public String alone(String message) throws Exception {
			JSONObject mess=  JSON.parseObject(message);
			 System.out.println("单独发, 一对一聊天"+message);
			  User user = new User();
			  user.setName("lmc168");
			  user.setAge(20);
			  user.setUserId(mess.getString("userId"));
			  this.template.convertAndSendToUser(user.getUserId()+"","/alone/getResponse",mess);
			 return message;
	     }
		

前端代码

<!DOCTYPE html>
<html>
  <head>
    <title>websocket.html</title>
	
    <meta name="keywords" content="keyword1,keyword2,keyword3">
    <meta name="description" content="this is my page">
    <meta name="content-type" content="text/html" charset="UTF-8">
    <!--<link rel="stylesheet" type="text/css" href="./styles.css">-->
	<!-- 独立css -->
	    <link href="/css/plugins/toastr/toastr.min.css" rel="stylesheet">

	
  </head>  
  <body>
	<div>  
	    <p id="response"></p>
	     <p id="id_test">触发打印消息</p>
	</div>
	<!-- 独立JS -->
	<script type="text/javascript" src="/js/jquery.min.js?v=2.1.4" charset="utf-8"></script>
	<script type="text/javascript" src="/js/webSocket/sockjs.min.js" charset="utf-8"></script>
	<script type="text/javascript" src="/js/webSocket/stomp.min.js" charset="utf-8"></script>
	<script src="/js/toastr/toastr.min.js"></script>
	
	<!-- <script type="text/javascript" src="/js/webSocket/stomp.js" charset="utf-8"></script> -->
  </body>
  
  <script type="text/javascript">
  var stompClient = null;	
  //加载完浏览器后  调用connect(),打开双通道
  $(function(){
	//打开双通道
	connect();
  })
  //强制关闭浏览器  调用websocket.close(),进行正常关闭
  window.onunload = function() {
  	disconnect()
  }
 
  function connect(){
      var socket = new SockJS('http://127.0.0.1:5080/endpointOyzc'); //连接SockJS的endpoint名称为"endpointOyzc"
      stompClient = Stomp.over(socket);//使用STMOP子协议的WebSocket客户端
      stompClient.connect({},function(frame){//连接WebSocket服务端     
          console.log('Connected:' + frame);
         // stompClient.send("/app/marco",{},'向服务端发送消息');  //后台需要 @MessageMapping("/marco")
          //通过stompClient.subscribe订阅/topic/getResponse 目标(destination)发送的消息
          stompClient.subscribe('/topic/getResponse',function(response){
              showResponse(JSON.parse(response.body));

  }

  //关闭双通道
  function disconnect(){
      if(stompClient != null) {
          stompClient.disconnect();
      }
      console.log("Disconnected");
  }
  function showResponse(message){
      var response = $("#response");
      response.append("<p>name: "+message.name+" 后台推送的数字 "+message.age+"</p>");
  }

  </script>
  
</html>

 

配置文件

        @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        //注册两个STOMP的endpoint,分别用于广播和点对点  ,并指定 SockJS协议。客户端就可以通过这个端点来进行连接;withSockJS作用是添加SockJS支持
          registry.addEndpoint("/endpointUser").withSockJS();    //指定谁能够收到令牌
    	  registry.addEndpoint("/endpointOyzc").setAllowedOrigins("*").withSockJS();  setAllowedOrigins 添加允许跨域访问
    	  //为/endpointOyzc路径启用SockJS功能
    	 // registry.addInterceptors(HandshakeInterceptor()) // 添加自定义拦截
         // registry.addEndpoint("/chatwebsocket").setAllowedOrigins("*").setHandshakeHandler(new MyHandsHandler()).withSockJS();
          registry.addEndpoint("/chatwebsocket").setAllowedOrigins("*").withSockJS();//使用配置的拦截方法configureWebSocketTransport

    }

   @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        // 使用RabbitMQ做为消息代理,替换默认的Simple Broker
    	//定义了服务端接收地址的前缀,也即客户端给服务端发消息的地址前缀,@SendTo(XXX) 也可以重定向
     // registry.setApplicationDestinationPrefixes("/app")
      // "STOMP broker relay"处理所有消息将消息发送到外部的消息代理
     registry.enableStompBrokerRelay("/exchange","/topic","/queue","/amq/queue")
        .setVirtualHost(rabbitProperties.getVirtualHost())
        .setRelayHost(rabbitProperties.getHost())
        .setClientLogin(rabbitProperties.getUsername())
        .setClientPasscode(rabbitProperties.getPassword())
        .setSystemLogin(rabbitProperties.getUsername())
        .setSystemPasscode(rabbitProperties.getPassword())
        .setSystemHeartbeatSendInterval(5000)
        .setSystemHeartbeatReceiveInterval(4000);
    }
    

代码比较乱,还是在github上看吧,

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
WebSocketRabbitMQ 可以结合使用实现实时消息推送。WebSocket 是一种基于 TCP 的协议,它允许在客户端和服务器之间建立持久的双向通信通道。而 RabbitMQ 是一个消息代理和队列管理系统,可以实现消息的可靠传输和分发。 下面是使用 WebSocketRabbitMQ 实现实时消息推送的一般步骤: 1. 配置 WebSocket 服务器:在后端应用程序中,你需要配置一个 WebSocket 服务器,用于接收和处理客户端的 WebSocket 连接请求。可以使用 Spring Boot 中的 Spring WebSocket 或其他 WebSocket 框架进行配置。 2. 配置 RabbitMQ:在后端应用程序中,你需要配置 RabbitMQ 的连接信息,并创建一个或多个交换机和队列。可以使用 RabbitMQ 的 Java 客户端库进行配置。 3. 监听 RabbitMQ 消息:在后端应用程序中,你需要监听 RabbitMQ 中指定队列的消息。当有新的消息到达时,通过 WebSocket 服务器将消息推送给客户端。 4. 前端连接 WebSocket:在前端应用程序中,你需要使用 JavaScript 的 WebSocket API 连接到后端的 WebSocket 服务器。 5. 接收消息并更新 UI:在前端应用程序中,当接收到 WebSocket 服务器推送的消息时,你可以在界面上实时展示或处理这些消息。 通过结合使用 WebSocketRabbitMQ,你可以实现实时、双向的消息通信,并将消息推送给多个客户端。这种方式适用于需要实时更新消息的应用场景,如聊天应用、实时监控等。需要根据具体的技术栈和需求进行相应的配置和开发。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值