本文主要阐述SpringBoot整合webSocket,实现主题订阅功能
第一步,引入webSocket依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
第二步,服务端配置webSocket
package com.***.gateway.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/webServer").setAllowedOrigins("*").withSockJS();
// setAllowedOrigins("*") 该设置为允许跨域访问
}
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/topic/");
}
}
第三步,服务开发接口,服务端对客户端订阅的主题发送消息接口,客户端推送消息到指定主题
package com.***.gateway.controller;
import com.alibaba.fastjson.JSONObject;
import com.***.common.web.Response;
import com.***.gateway.entity.SockeMessage;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.cloud.netflix.zuul.filters.Route;
import org.springframework.cloud.netflix.zuul.filters.RouteLocator;
import org.springframework.messaging.handler.annotation.DestinationVariable;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.messaging.simp.annotation.SubscribeMapping;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.client.RestTemplate;
@Slf4j
@Controller
public class WebSocketController {
@Autowired
private SimpMessagingTemplate simpMessagingTemplate;
@Autowired
private LoadBalancerClient loadBalancerClient;
@Autowired
private RouteLocator routeLocator;
@SubscribeMapping("/topic/getResponse/{topicId}")
public String subscribe(@DestinationVariable String topicId) {
log.info("初始化订阅消息:topic = {}",topicId);
return "初始化订阅消息" + topicId;
}
@MessageMapping("/onMessage/{serviceId}/{method}")
@SendTo("/topic/onMessage")
public String onMessage(SockeMessage message, @DestinationVariable String serviceId, @DestinationVariable String method) {
return "客户端发送的消息为:" + message.getMessage();
}
@ResponseBody
@GetMapping("/serverMessage/{topicId}")
public void serverMessage(@PathVariable String topicId, String message) {
simpMessagingTemplate.convertAndSend("/topic/getResponse/" + topicId, message);
}
@ResponseBody
@PostMapping("/serverMessage/post/{topicId}")
public void serverMessage2(@PathVariable String topicId, String message) {
simpMessagingTemplate.convertAndSend("/topic/getResponse/" + topicId, message);
}
}
第四步,前端代码开发,实现订阅主题,通过订阅的主题发送消息
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>websocket通讯</title>
</head>
<script src="https://cdn.bootcss.com/sockjs-client/1.3.0/sockjs.min.js" ></script>
<script src="https://cdn.bootcss.com/stomp.js/2.3.3/stomp.js" ></script>
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"></script>
<script>
var socket;
var stompClient = null;
function openSocket() {
var socket = new SockJS("http://localhost:10000/webServer");
stompClient = Stomp.over(socket);
stompClient.connect({}, function(frame) {
<!-- 订阅主题dpweb -->
stompClient.subscribe('/topic/getResponse/dpweb', function(response){
console.log(response)
});
});
}
function disconnect() {
if (stompClient != null) {
stompClient.disconnect();
}
console.log("Disconnected");
}
function unsubscribe() {
console.log(stompClient.subscriptions);
for (var sub in stompClient.subscriptions) {
if (stompClient.subscriptions.hasOwnProperty(sub)) {
stompClient.unsubscribe(sub);
}
}
}
function resubscribe(){
stompClient.subscribe('/topic/getResponse/rbac', function(response){
console.log(response);
});
}
function sendName() {
stompClient.send("/onMessage/dpweb/save", {},JSON.stringify({'message': '123'}));
}
</script>
<body>
<div><a onclick="openSocket()">开启socket</a></div>
<div><a onclick="disconnect()">断开socket</a></div>
<div><a onclick="unsubscribe()">退订</a></div>
<div><a onclick="resubscribe()">订阅</a></div>
<div><input type="text" id="name" /><a onclick="sendName()">发送</a></div>
</body>
</html>