STOMP 消息高可用推送

1、背景

前端在部分消息需要实时推送,如果需要推送的终端比较多并且消息的准确性要求比较高,因此需要采用高可用

2、高可用方案

2.1 Websocket

Websocket+gateway网关

缺点:

  1. 实现起来有一定困难
  2. 基于gateway网关,对网关会造成一定性能压力

2.2 Stomp

        借用消息中间件实现高可用,如RabbitMQ、RocketMQ都支持Stomp协议。后端直接搭建消息高可用集群,前端通过Stomp协议直接连接消息中间件,进行消息订阅和发布。应用服务同样进行消息的订阅或发布。

2.2.1 STOMP协议

STOMP即Simple (or Streaming) Text Orientated Messaging Protocol,简单(流)文本定向消息协议,它提供了一个可互操作的连接格式,允许STOMP客户端与任意STOMP消息代理(Broker)进行交互。STOMP协议由于设计简单,易于开发客户端,因此在多种语言和多种平台上得到广泛地应用。

2.2.2 前端调用示例

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8" />
    <title>Websocket</title>
    <noscript>
        <h2 style="color:#ff0000">貌似你的浏览器不支持websocket</h2>
    </noscript>
    <script src="js/sockjs.min.js"></script>
    <script src="js/stomp.min.js"></script>
    <script src="js/jquery-3.4.1.min.js"></script>

    <script type="text/javascript">
	
    var host="ws://192.168.56.101:15674/ws";
	
    function login() {
		host=$("#host").val();
        connect();
    }

    var stompClient = null;

    function setConnected(connected) {
		$('#disconnect').attr("disabled",false);
        $('#response').html();
    }
    function connect() {
        //地址+端点路径,构建websocket链接地址
	    var headers = {
			"login": "admin",
			"passcode": "admin",
			//虚拟主机,默认“/”
			"host": "/"
		};
		
        var username = document.getElementById("username").value;
        stompClient = Stomp.client(host);
        stompClient.connect(headers, function(frame) {
            setConnected(true);
            console.log('Connected:' + frame);
			showResponse('Connected');
			
			$("#message-container").show();
			$('#loginButton').attr("disabled",true);
			
            stompClient.subscribe('/queue/' + username, function(response) {
                showResponse(response.body);
            });
        },function(frame) {
            console.log('Connect fail:' + frame);
			showResponse('Connect fail:' + frame);
  
        });
    }
    function disconnect() {
        if (stompClient != null) {
            stompClient.disconnect();
        }
        setConnected(false);
        console.log("Disconnected");
		showResponse("Disconnected");
    }
	
    function send() {
        var username = $('#username').val();
        var message = $('#message').val();
        //发送消息的路径
        stompClient.send('/queue/' + username, {"content-type":"text/plain"}, JSON.stringify({username:username,message:message}));
    }
	
    function showResponse(message) {
        var response = $('#response');
		var html="<div><b>"+dateFormat("YYYY-mm-dd HH:MM:SS",new Date())+"</b>  :"+message+"</div>"
        response.append(html);
    }
	
	function dateFormat(fmt, date){
		let ret;
		const opt = {
			"Y+": date.getFullYear().toString(),        // 年
			"m+": (date.getMonth() + 1).toString(),     // 月
			"d+": date.getDate().toString(),            // 日
			"H+": date.getHours().toString(),           // 时
			"M+": date.getMinutes().toString(),         // 分
			"S+": date.getSeconds().toString()          // 秒
			// 有其他格式化字符需求可以继续添加,必须转化成字符串
		};
		for (let k in opt) {
			ret = new RegExp("(" + k + ")").exec(fmt);
			if (ret) {
				fmt = fmt.replace(ret[1], (ret[1].length == 1) ? (opt[k]) : (opt[k].padStart(ret[1].length, "0")))
			};
		};
		return fmt;
	}
</script>
</head>
<body>
 
    <div style="">
	    <div>
			<span>地址</span>
			<input type="text"  placeholder="服务器地址" id="host" style="width: 200px" value="ws://192.168.56.101:15674/ws"/>
			<br/>
			<span>用户</span>
			<input type="text"  placeholder="请输入用户名" id="username" style="width: 200px" value="jack"/>
		
		</div>
        <button type="button" id="loginButton" onclick="login()">登录</button>
        <button type="button" id="disconnect" onclick="disconnect();" disabled>断开连接</button>
    </div>
	 <div style="">
	    <div id="message-container" style="display:none">
			<span>消息</span>
			<input type="text" id="message" style="width: 200px" value="hello,world!"/>
			<button type="button" id="send" onclick="send()">发送</button>
		</div>
    </div>
	
    <div style="height: 400px;border: 1px solid black;padding:10px;width:300px;overflow-y:auto;">
        <div id="response"></div>
    </div>
 
</body>
</html>

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Boot提供了一个非常方便的方式来整合WebSocketSTOMP协议,可以非常容易地在应用程序中添加实时消息推送功能。下面是实现的步骤: 1.添加依赖 在pom.xml中添加以下依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency> ``` 2.创建WebSocket配置类 创建一个类来配置WebSocket支持: ```java @Configuration @EnableWebSocketMessageBroker public class WebSocketConfig implements WebSocketMessageBrokerConfigurer { @Override public void configureMessageBroker(MessageBrokerRegistry registry) { registry.enableSimpleBroker("/topic"); registry.setApplicationDestinationPrefixes("/app"); } @Override public void registerStompEndpoints(StompEndpointRegistry registry) { registry.addEndpoint("/ws").setAllowedOrigins("*").withSockJS(); } } ``` 该类通过@EnableWebSocketMessageBroker注解启用了WebSocket消息代理功能,并实现了WebSocketMessageBrokerConfigurer接口来配置消息代理。 configureMessageBroker()方法配置了一个简单的消息代理,它将以“/topic”为前缀的消息发送到代理。应用程序的目标前缀将是“/app”。 registerStompEndpoints()方法将“/ws”路径注册为STOMP端点,并启用SockJS支持。 3.编写控制器 创建一个控制器来处理WebSocket请求: ```java @Controller public class WebSocketController { @MessageMapping("/hello") @SendTo("/topic/greetings") public Greeting greeting(HelloMessage message) throws Exception { Thread.sleep(1000); // simulated delay return new Greeting("Hello, " + message.getName() + "!"); } } ``` @MessageMapping注解表示该方法可以处理来自“/app/hello”的消息。@SendTo注解表示当处理完成后,将结果发送到“/topic/greetings”主题。 4.创建实体类 创建HelloMessage和Greeting实体类: ```java public class HelloMessage { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } } public class Greeting { private String content; public Greeting(String content) { this.content = content; } public String getContent() { return content; } } ``` 5.创建前端页面 在前端页面中使用STOMP.js和SockJS来连接WebSocket,发送和接收消息: ```html <!DOCTYPE html> <html> <head> <title>WebSocket Example</title> <script src="https://cdn.jsdelivr.net/sockjs/1.1.4/sockjs.min.js"></script> <script src="https://cdn.jsdelivr.net/stomp.js/2.3.3/stomp.min.js"></script> <script src="https://code.jquery.com/jquery-3.5.1.min.js"></script> </head> <body> <div> <label for="name">What is your name?</label> <input type="text" id="name" name="name"> <button id="connect">Connect</button> </div> <br/> <div> <label for="message">Message:</label> <input type="text" id="message" name="message"> <button id="send">Send</button> </div> <br/> <div id="greetings"></div> <script> var stompClient = null; function connect() { var socket = new SockJS('/ws'); stompClient = Stomp.over(socket); stompClient.connect({}, function(frame) { console.log('Connected: ' + frame); stompClient.subscribe('/topic/greetings', function(greeting){ showGreeting(JSON.parse(greeting.body).content); }); }); } function disconnect() { if (stompClient !== null) { stompClient.disconnect(); } console.log("Disconnected"); } function sendName() { stompClient.send("/app/hello", {}, JSON.stringify({'name': $("#name").val()})); } function showGreeting(message) { $("#greetings").append("<tr><td>" + message + "</td></tr>"); } $(function () { $("form").on('submit', function (e) { e.preventDefault(); }); $("#connect").click(function() { connect(); }); $("#disconnect").click(function() { disconnect(); }); $("#send").click(function() { sendName(); }); }); </script> </body> </html> ``` 在页面中,我们使用了SockJS和STOMP.js,创建一个WebSocket连接。我们可以使用connect()函数来建立连接,使用sendName()函数来发送消息,并使用showGreeting()函数来显示接收到的消息。 最后,我们需要在应用程序的主类上添加@SpringBootApplication注解,并运行应用程序。 这样,当用户在页面上输入一个名字并点击“Connect”按钮时,将建立一个WebSocket连接,并向服务器发送一个消息。服务器将在1秒钟后返回一个问候语,并将其发送到“/topic/greetings”主题。浏览器将接收到这个消息,并通过showGreeting()函数显示它。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值