WebSocket是一种双向通信协议。在建立连接后,WebSocket服务器端和客户端都能主动向对方发送或接收数据。
测试效果
发送请求,触发WebSocket
发消息到客户端
客户端接收到服务端发过来的消息
快速开始
WebSocket服务端
-
pom.xml
加入依赖<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency>
-
添加配置类
@Configuration @EnableWebSocketMessageBroker //注解开启STOMP协议来传输基于代理的消息 public class WebSocketConfig implements WebSocketMessageBrokerConfigurer { /** * 这是一个端点(endpoint),客户端在订阅或发布消息到目的地路径前,要连接到该端点。 * @param registry */ @Override public void registerStompEndpoints(StompEndpointRegistry registry) { registry.addEndpoint("/endpoint") .setAllowedOrigins("*") .withSockJS(); } /** * 配置消息代理(Message Broker) * @param config */ @Override public void configureMessageBroker(MessageBrokerRegistry config) { //基于内存的STOMP消息代理 /** * 放开的前缀路由,放开topic和queue路由,客户端才能接收到对应路由开头的消息 * topic用来广播,queue用来实现单播 */ config.enableSimpleBroker("/topic", "/queue"); /** * 客户端发消息到服务端,拥有@MessageMapping注解的方法路劲上 ,需要添加的前缀 */ config.setApplicationDestinationPrefixes("/app"); //单播时,默认前缀为/user,现修改为/queue config.setUserDestinationPrefix("/queue"); } }
-
编写业务代码
@RestController @Api(value = "WebSocket发送消息", tags = {"WebSocket控制器"}) public class SubController { @Autowired private WebSocketService webSocketService; /** * 客户端发送到服务端的接口,客户端需要添加/app前缀, * 如需要修改前缀,在sakura-websocket脚手架中的com.sakura.common.websocket.config.WebSocketConfig类中修改 */ @MessageMapping("/queue/check") public void check() { InMessage<String> im = new InMessage<>(); im.setContent("topicCheck"); im.setTo("27"); im.setMsgType(200); webSocketService.queue(im); } @PostMapping("/queue") @ApiOperation("单播") public void queue() { InMessage<String> im = new InMessage<>(); im.setContent("queue"); im.setTo("27"); im.setMsgType(200); webSocketService.queue(im); } @PostMapping("/subscribe") @ApiOperation("广播") public void subscribe() { InMessage<String> im = new InMessage<>(); im.setContent("subscribe"); im.setTo("27"); im.setMsgType(200); webSocketService.subscribe(im); } @PostMapping("/sendMessage") @ApiOperation("单播或广播,根据sendUrl判断") public void sendMessage(@RequestBody ContentMessage message) { webSocketService.sendMessage(message); } }
WebSocket客户端
js
订阅代码
var stompClient = null;
function setConnected(connected) {
$("#connect").prop("disabled", connected);
$("#disconnect").prop("disabled", !connected);
if (connected) {
$("#conversation").show();
}
else {
$("#conversation").hide();
}
$("#greetings").html("");
}
function connect() {
//后端放开的端点
var socket = new SockJS('http://localhost:8096/endpoint');
stompClient = Stomp.over(socket);
stompClient.connect({}, function (frame) {
setConnected(true);
console.log('Connected: ' + frame);
//单播
stompClient.subscribe('/queue/27/message', function (greeting) {
showGreeting(greeting.body);
});
//广播
/**
stompClient.subscribe('/topic/27/message', function (greeting) {
showGreeting(greeting.body);
});
*/
});
}
function disconnect() {
if (stompClient !== null) {
stompClient.disconnect();
}
setConnected(false);
console.log("Disconnected");
}
function sendName() {
//需要添加服务端配置类中设置的/app前缀
stompClient.send("/app/queue/check", {}, $("#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(); });
});