SpringBoot 整合 WebSocket(topic广播)

  1、什么是WebSocket
  
  WebSocket为游览器和服务器提供了双工异步通信的功能,即游览器可以向服务器发送消息,服务器也可以向游览器发送消息。WebSocket需游览器的支持,如IE10、Chrome 13+、Firefox 6+,这对我们现在的游览器来说都不是问题。
  
  WebSocket是通过一个socket来实现双工异步通讯能力的。但是直接使用WebSocket(或SockJS:WebSocket协议的模拟,增加了当游览器不支持WebSocket的时候的兼容支持)协议开发程序显得特别繁琐, 我们会使用它的子协议STOMP,它是一个更高级别的协议,STOMP协议使用一个基于帧的格式来定义消息,与HTTP的request和reponse类似(具有类似于@RequestMapping的@MassageMapping)
  
  2、什么是STOMP
  
  STOMP,Streaming Text Orientated Message Protocol,是流文本定向消息协议,是一种为MOM(Message Oriented Middleware,面向消息的中间件)设计的简单文本协议。
  
  它提供了一个可互操作的连接格式,允许STOMP客户端与任意STOMP消息代理(Broker)进行交互,类似于OpenWire(一种二进制协议)。由于其设计简单,很容易开发客户端,因此在多种语言和多种平台上得到广泛应用。其中最流行的STOMP消息代理是Apache ActiveMQ。
  
  STOMP协议工作于TCP协议之上,使用了下列命令:
  
    1)、SEND 发送
  
    2)、SUBSCRIBE 订阅
  
    3)、UNSUBSCRIBE 退订
  
    4)、BEGIN 开始
  
    5)、COMMIT 提交
  
    6)、ABORT 取消
  
    7)、ACK 确认
  
    8)、DISCONNECT 断开
  
  3、为什么需要WebSocket
  
  答案很简单,因为 HTTP 协议有一个缺陷:通信只能由客户端发起。
  
  举例来说,我们想了解今天的天气,只能是客户端向服务器发出请求,服务器返回查询结果。HTTP 协议做不到服务器主动向客户端推送信息。如果想持续从服务的获取消息,则只能使用轮询或建立长连接的方法来实现,但是这样或浪费很多不必要的资源。而webSocket则解决了这个问题,通信可由双方发起,只需要建立一次连接,服务的端就可以持续从服务端获得消息。主要用来做消息通知,消息推送等模块
  
  4、SpringBoot使用 STOMP 消息步骤
  
  1)、添加pom文件依赖
  
  2)、java方式配置websocket stomp
  
  3)、消息实体类
  
  4)、书写控制层
  
  5)、书写页面
  
  5、Pom 依赖
  
  复制代码
  
  <dependency>
  
  <groupId>org.springframework.boot</groupId>
  
  <artifactId>spring-boot-starter-thymeleaf</artifactId>
  
  </dependency>
  
  <dependency>
  
  <groupId>org.springframework.boot</groupId>
  
  <artifactId>spring-boot-starter-websocket</artifactId>
  
  </dependency>
  
  复制代码
  
  6、java方式配置websocket stomp

  package com.example.demo.config;
  
  import org.springframework.context.annotation.Configuration;
  
  import org.springframework.messaging.simp.config.MessageBrokerRegistry;
  
  import org.springframework.web.socket.config.annotation.AbstractWebSocketMessageBrokerConfigurer;
  
  import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
  
  import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
  
  @Configuration
  
  @EnableWebSocketMessageBroker
  
  public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
  
  /**
  
  * 配置链接端点
  
  * @param registry
  
  */
  
  @Override
  
  public void registerStompEndpoints(StompEndpointRegistry registry){
  
  registry.addEndpoint("/endpointWisely").withSockJS();
  
  }
  
  /**
  
  * 配置消息代理
  
  * @param registry
  
  */
  
  @Override
  
  public void configureMessageBroker(MessageBrokerRegistry registry){
  
  registry.enableSimpleBroker("/topic");
  
  }
  
  }
  
  7、消息实体类
  
  复制代码
  
  package com.example.demo.PoJo;
  
  /**
  
  * 消息接受
  
  */
  
  public class WiselyMessage {
  
  private String name;
  
  public String getName(){
  
  return name;
  
  }
  
  }
  
  复制代码
  
  复制代码
  
  package com.example.demo.PoJo;
  
  /**
  
  * 消息返回
  
  */
  
  public class WiselyResponse {
  
  private String responseMessage;
  
  public WiselyResponse(String responseMessage){
  
  this.responseMessage = responseMessage;
  
  }
  
  public String getResponseMessage(){
  
  return responseMessage;
  
  }
  
  }
  
  复制代码
  
  8、书写控制层
  
  复制代码
  
  package com.example.demo.controller;
  
  import com.example.demo.PoJo.WiselyMessage;
  
  import com.example.demo.PoJo.WiselyResponse;
  
  import org.springframework.beans.factory.annotation.Autowired;
  
  import org.springframework.messaging.handler.annotation.MessageMapping;
  
  import org.springframework.messaging.handler.annotation.SendTo;
  
  import org.springframework.messaging.simp.SimpMessagingTemplate;
  
  import org.springframework.stereotype.Controller;
  
  import java.security.Principal;
  
  @Controller
  
  public class WsController {
  
  /**
  
  * MessageMapping 类似于 RequestMapping
  
  * SendTo 订阅地址 类似于 订阅一个URL (我的理解就是 调用了这个方法 在返回的时候会给订阅该url的地址发送数据)
  
  * @param message
  
  * @return
  
  * @throws Exception
  
  */
  
  @MessageMapping("/welcome")
  
  @SendTo("/topic/getResponse")
  
  public WiselyResponse say(WiselyMessage message) throws Exception {
  
  Thread.sleep(3000);
  
  return new WiselyResponse("Welcome," + message.getName() + "!");
  
  }
  
  }
  
  复制代码
  
  9、书写页面
  
  复制代码
  
  <!DOCTYPE html>
  
  <html xmlns:th="http://www.michenggw.com/">
  
  <head>
  
  <meta charset="UTF-8" />
  
  <title>Spring Boot+WebSocket+广播式</title>
  
  </head>
  
  <body onload="disconnect()">
  
  <noscript><h2 style="color: #ff0000">貌似你的浏览器不支持websocket</h2></noscript>
  
  <div>
  
  <div>
  
  <button id="connect" onclick="connect();">连接</button>
  
  <button id="disconnect" disabled="disabled" onclick="disconnect();">断开连接</button>
  
  </div>
  
  <div id="conversationDiv">
  
  <label>输入你的名字</label>www.furggw.com<input type="text" id="name" />
  
  <button id="sendName" onclick="sendName();">发送</button>
  
  <p id="response"></p>
  
  </div>
  
  </div>
  
  <script th:src="@{sockjs.min.js}"></script>
  
  <script th:src="@{stomp.min.js}"></script>
  
  <script th:src="@{jquery.js}"></script>
  
  <script type="text/javascript">
  
  var stompClient = null;
  
  function setConnected(connected) {
  
  document.getElementById('connect').disabled = connected;
  
  document.getElementById('disconnect').disabled = !connected;
  
  document.getElementById('conversationDiv').style.visibility = connected ? 'visible' : 'hidden';
  
  $('#response').html();
  
  }
  
  function connect() {
  
  var socket = new SockJS('/endpointWisely'); //1
  
  stompClient = Stomp.over(socket);
  
  stompClient.connect({}, function(frame) {
  
  setConnected(true);
  
  console.log('Connected: ' + frame);
  
  stompClient.subscribe('/topic/getResponse', function(respnose){ //2
  
  showResponse(JSON.parse(respnose.body).responseMessage);
  
  });
  
  });
  
  }
  
  function disconnect() {
  
  if (stompClient != null) {
  
  stompClient.disconnect();
  
  }
  
  setConnected(false);
  
  console.log("Disconnected");
  
  }
  
  function sendName() {
  
  var name = $('#name').val();
  
  //3
  
  stompClient.send("/welcome", {}, JSON.stringify({ 'name': name }));
  
  }
  
  function showResponse(message) {
  
  var response = $("#response");
  
  response.html(message);
  
  }
  
  </script>
  
  </body>
  
  </html>

猜你喜欢

转载自blog.csdn.net/li123128/article/details/84919839