赞
踩
在 Spring Boot 中,SockJS
是一个用于实现 WebSocket 的兼容性解决方案。本文将介绍 SockJS
的原理、使用方法和示例代码。
SockJS
是一种浏览器与服务器之间的通信协议,它可以在浏览器和服务器之间建立一个基于 HTTP 的双向通信通道。SockJS
的主要作用是提供一种 WebSocket 的兼容性解决方案,使得不支持 WebSocket 的浏览器也可以使用 WebSocket。
SockJS
实现了一个 WebSocket 的兼容层,它可以在浏览器和服务器之间建立一个基于 HTTP 的通信通道,然后通过这个通道进行双向通信。当浏览器不支持 WebSocket 时,SockJS
会自动切换到使用轮询(polling)或长轮询(long-polling)的方式进行通信。
SockJS
的原理是通过建立一个基于 HTTP 的通信通道来实现 WebSocket 的双向通信。当浏览器支持 WebSocket 时,SockJS
会直接使用 WebSocket 进行通信;当浏览器不支持 WebSocket 时,SockJS
会自动切换到使用轮询(polling)或长轮询(long-polling)的方式进行通信。
在使用 SockJS
时,首先需要在客户端和服务器端分别引入 sockjs-client.js
和 sockjs-server
,然后在客户端通过 new SockJS(url)
的方式建立一个 SockJS
连接。
客户端和服务器端之间的通信是基于事件的,当客户端发送消息时,服务器端会触发一个 onmessage
事件,然后将消息发送回客户端。客户端在接收到消息后,会触发一个 onmessage
事件,然后处理收到的消息。
使用 SockJS
非常简单,在 Spring Boot 中,只需要在配置文件中添加以下内容即可:
spring:
websocket:
enabled: true
broker:
relay-host: localhost
relay-port: 61613
user: guest
password: guest
relay-path: /stomp
以上配置表示启用 WebSocket,并将消息发送到 localhost
的 61613
端口,使用 guest/guest
的用户名和密码进行认证,使用 /stomp
路径进行消息传输。
接下来,我们需要在客户端中建立一个 SockJS
连接,并实现 onmessage
事件的回调方法。代码如下:
var socket = new SockJS('/gs-guide-websocket');
stompClient = Stomp.over(socket);
stompClient.connect({}, function(frame) {
stompClient.subscribe('/topic/greetings', function(greeting){
showGreeting(JSON.parse(greeting.body).content);
});
});
以上代码中,new SockJS('/gs-guide-websocket')
表示使用 /gs-guide-websocket
路径建立一个 SockJS
连接。stompClient.connect({}, function(frame){...})
表示连接成功后执行的回调方法,stompClient.subscribe('/topic/greetings', function(greeting){...})
表示订阅 /topic/greetings
目的地,当有消息发布到该目的地时触发回调方法。
最后,我们需要在服务器端实现消息发送和接收的功能。代码如下:
@Configuration @EnableWebSocketMessageBroker public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer { @Override public void configureMessageBroker(MessageBrokerRegistry registry) { registry.enableStompBrokerRelay("/topic") .setRelayHost("localhost") .setRelayPort(61613) .setClientLogin("guest") .setClientPasscode("guest") .setSystemHeartbeatSendInterval(5000) .setSystemHeartbeatReceiveInterval(4000); registry.setApplicationDestinationPrefixes("/app"); } @Override public void registerStompEndpoints(StompEndpointRegistry registry) { registry.addEndpoint("/gs-guide-websocket").withSockJS(); } }
以上代码中,@EnableWebSocketMessageBroker
注解表示启用 WebSocket 消息代理,configureMessageBroker
方法用于配置消息代理,registerStompEndpoints
方法用于注册 SockJS
端点。
接下来,我们需要在控制器中实现消息发送和接收的功能。代码如下:
@Controller
public class GreetingController {
@MessageMapping("/hello")
@SendTo("/topic/greetings")
public Greeting greeting(HelloMessage message) throws Exception {
Thread.sleep(1000); // simulated delay
return new Greeting("Hello, " + HtmlUtils.htmlEscape(message.getName()) + "!");
}
}
以上代码中,@MessageMapping("/hello")
注解表示处理 /hello
目的地的消息,@SendTo("/topic/greetings")
注解表示将处理结果发送到 /topic/greetings
目的地。greeting
方法实现了消息的处理逻辑。
以下是一个完整的示例代码,包括客户端和服务器端的代码:
<!DOCTYPE html> <html> <head> <title>Hello WebSocket</title> <script src="/webjars/sockjs-client/1.1.2/dist/sockjs.min.js"></script> <script src="/webjars/stomp-websocket/2.3.3/dist/stomp.min.js"></script> <script src="/js/app.js"></script> </head> <body> <div> <label>What is your name?</label> <input type="text" id="name" /> <button type="button" onclick="send()">Send</button> </div> <div id="greetings"> </div> </body> </html>
var socket = new SockJS('/gs-guide-websocket'); stompClient = Stomp.over(socket); stompClient.connect({}, function(frame) { stompClient.subscribe('/topic/greetings', function(greeting){ showGreeting(JSON.parse(greeting.body).content); }); }); function send() { var name = document.getElementById('name').value; stompClient.send("/app/hello", {}, JSON.stringify({ 'name': name })); } function showGreeting(message) { var div = document.createElement('div'); div.appendChild(document.createTextNode(message)); document.getElementById('greetings').appendChild(div); }
@Configuration @EnableWebSocketMessageBroker public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer { @Override public void configureMessageBroker(MessageBrokerRegistry registry) { registry.enableStompBrokerRelay("/topic") .setRelayHost("localhost") .setRelayPort(61613) .setClientLogin("guest") .setClientPasscode("guest") .setSystemHeartbeatSendInterval(5000) .setSystemHeartbeatReceiveInterval(4000); registry.setApplicationDestinationPrefixes("/app"); } @Override public void registerStompEndpoints(StompEndpointRegistry registry) { registry.addEndpoint("/gs-guide-websocket").withSockJS(); } } @Controller public class GreetingController { @MessageMapping("/hello") @SendTo("/topic/greetings") public Greeting greeting(HelloMessage message) throws Exception { Thread.sleep(1000); // simulated delay return new Greeting("Hello, " + HtmlUtils.htmlEscape(message.getName()) + "!"); } } 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; } }
以上代码实现了一个简单的聊天室,用户在输入框中输入自己的名字,然后点击发送按钮,将消息发送到服务器端,服务器端将收到的消息处理后发送回客户端,客户端显示收到的消息。当多个用户同时使用该聊天室时,每个用户都可以看到其他用户发送的消息。
本文介绍了 Spring Boot 中的 SockJS
,包括 SockJS
的原理、
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。