集群方案如下:
- 采用Redis的订阅与发布,由于Websocket无法被序列化,不能进行缓存,所以不能直接将websocket消息缓存到Redis中。
- 采用单纯的RabbitMQ,利用fanout\topic进行消息订阅,将Websocket消息结果发送到消息队列中,在进行转发接收。参考代码
- 采用RabbitMQ+MQTT消息协议,可以在RabbitMQ官网上看到
- 采用RabbitMQ+STOMP消息协议,可以在RabbitMQ官网上看到【推荐使用】
接下来介绍如何使用RabbitMQ+STOMP,代码如下
maven
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--websocket 相关依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>webjars-locator-core</artifactId>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>sockjs-client</artifactId>
<version>1.0.2</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>stomp-websocket</artifactId>
<version>2.3.3</version>
</dependency>
<!--rabbitmq-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
</dependencies>
配置文件
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");
config.setApplicationDestinationPrefixes("/app");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/websocket").setAllowedOrigins("*").withSockJS();
}
}
接收消息并发送
@CrossOrigin(allowCredentials = "true", allowedHeaders = "*")
@RestController
public class WebSocketTestController {
@Autowired
private SimpMessagingTemplate messagingTemplate;
@MessageMapping("/chat")
public void messageHandling(RequestMessage requestMessage) throws Exception {
String destination = "/topic/" + HtmlUtils.htmlEscape(requestMessage.getRoom());
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 WebSocket</title>
<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()">连接WebSocket</button>
<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;
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']+ '<br/>';
});
});
}
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",
'content': message,
'userId':"566072523",
'questionId':"222299023",
'createTime':"",
})
);
}
function disconnect() {
if (this.stompClient !== undefined) {
this.stompClient.disconnect();
alert("Disconnected");
}else{
alert("当前没有连接websocket")
}
this.stompClient = undefined;
}
</script>
</html>
|