SpringBoot Websocket 集群方案

集群方案如下:

  1. 采用Redis的订阅与发布,由于Websocket无法被序列化,不能进行缓存,所以不能直接将websocket消息缓存到Redis中。
  2. 采用单纯的RabbitMQ,利用fanout\topic进行消息订阅,将Websocket消息结果发送到消息队列中,在进行转发接收。参考代码
  3. 采用RabbitMQ+MQTT消息协议,可以在RabbitMQ官网上看到
  4. 采用RabbitMQ+STOMP消息协议,可以在RabbitMQ官网上看到【推荐使用】
  5. 还能够利用负载均衡的源地址哈希法,将ip通过一定的hash算法转发到一台固定的服务器(这个的话,对代码几乎没有改动,不过缺点也比较大)

接下来介绍如何使用RabbitMQ+STOMP,代码如下

maven


        
            org.springframework.boot
            spring-boot-starter-web
        

        
            org.springframework.boot
            spring-boot-starter-tomcat
            provided
        
        
            org.springframework.boot
            spring-boot-starter-test
            test
            
                
                    org.junit.vintage
                    junit-vintage-engine
                
            
        


        
        
            org.springframework.boot
            spring-boot-starter-websocket
        
        
            org.webjars
            webjars-locator-core
        
        
            org.webjars
            sockjs-client
            1.0.2
        
        
            org.webjars
            stomp-websocket
            2.3.3
        

        
        
            org.springframework.boot
            spring-boot-starter-amqp
        


        
        commons-lang
        commons-lang
        2.6
        

    

配置文件

spring:
  rabbitmq:
    host: 192.168.66.10
    port: 5672
    username: guest
    password: guest

RabbitMQ配置类

@Configuration
public class RabbitConfig {
 
    @Bean
    public Queue helloQueue() {
        return new Queue("hello");
    }
 
}

Websocket配置类


@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
 
    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        /**
         * 配置简单的消息代理
         */
        config.enableSimpleBroker("/topic","/all");
 
        /**
         * 客户端发送过来的消息,需要以"/app"为前缀,再经过Broker转发给响应的Controller
         */
        config.setApplicationDestinationPrefixes("/app");
    }
 
    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
 
        /**
         * 路径"/websocket"被注册为STOMP端点,对外暴露,客户端通过该路径接入WebSocket服务
         */
        registry.addEndpoint("/websocket").setAllowedOrigins("*").withSockJS();
    }
 
 
}

接收消息并发送

@CrossOrigin(allowCredentials = "true", allowedHeaders = "*")
@RestController
public class WebSocketTestController {
 
    @Autowired
    private SimpMessagingTemplate messagingTemplate;

 

    //RequestMessage消息结果集
    @MessageMapping("/chat")
    public void messageHandling(RequestMessage requestMessage) throws Exception {
        String destination = "/topic/" + HtmlUtils.htmlEscape(requestMessage.getRoom());//htmlEscape  转换为HTML转义字符表示

        String content = HtmlUtils.htmlEscape(requestMessage.getContent());

 
        System.out.println( requestMessage.getRoom() );
        System.out.println( content );
 
 
      
 
        messagingTemplate.convertAndSend(destination, requestMessage);
    }
 
}

前端页面

DOCTYPE HTML>
<html>
<head>
    <meta charset="UTF-8">
    <title>My WebSockettitle>

    <script src="js/sockjs.min.js">script>
    <script src="js/jquery.min.js">script>
    <script src="js/stomp.min.js">script>
    

    <style>
        #message22{
            margin-top:40px;
            border:1px solid gray;
            padding:20px;
        }
    style>

    <style>
        #message{
            margin-top:40px;
            border:1px solid gray;
            padding:20px;
        }
    style>

head>

<body>

频道号:<input id="room" type="text"/>
<button onclick="conectWebSocket()">连接WebSocketbutton>
<button onclick="disconnect()">断开连接button>
<hr />

<div id="message22">div>


<br />
做题区:<input id="text" type="text" />
 频道号:<input id="toUser" type="text" />
<button onclick="sendMessage()">发送消息button>
<div id="message">div>
body>

<script type="text/javascript">
    var stompClient;

    var serverUrl = "http://localhost:8080/websocket";

    var room;//频道号


    var websocket = null;

    //websocket连接
    function conectWebSocket(){

        this.room = document.getElementById('room').value;//频道号


        console.log(this.serverUrl);

        var socket = new SockJS(this.serverUrl);
        console.log(socket)
        this.stompClient = Stomp.over(socket);
        var that = this;
        this.stompClient.connect({}, function (frame) {
            //订阅消息
            that.stompClient.subscribe('/topic/'+that.room ,function(txt) {
                document.getElementById('message').innerHTML += JSON.parse(txt.body)['content']+ '
'
; }); }); } //发送消息 function sendMessage() { //获取输入的文本信息进行发送 var message = document.getElementById('text').value; var room = document.getElementById('toUser').value; this.stompClient.send( '/app/chat', {}, JSON.stringify({ 'room': room, 'type': "1",//1,2 'content': message, 'userId':"566072523",//小明 'questionId':"222299023",//题目1 'createTime':"", }) ); } function disconnect() { //断开连接的方法 if (this.stompClient !== undefined) { this.stompClient.disconnect(); alert("Disconnected"); }else{ alert("当前没有连接websocket") } this.stompClient = undefined; }
script> html>

你可能感兴趣的:(笔记,websocket,rabbitmq,java)