spring -mvc - @EnableWebSocket
@EnableWebSocket
1.在Spring中启用WebSocket
首先,我们启用 WebSocket 功能。为此,我们需要向应用程序添加配置并使用@EnableWebSocketMessageBroker注释此类。
顾名思义,它支持 WebSocket 消息处理,并由消息代理支持:
@Configuration @EnableWebSocketMessageBroker public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer { @Override public void configureMessageBroker(MessageBrokerRegistry config) { config.enableSimpleBroker("/topic"); config.setApplicationDestinationPrefixes("/app"); } @Override public void registerStompEndpoints(StompEndpointRegistry registry) { registry.addEndpoint("/chat"); registry.addEndpoint("/chat").withSockJS(); } }
这里我们可以看到configureMessageBroker方法用于配置消息代理。
首先,我们启用内存中消息代理将消息返回到前缀为“/topic”的目的地上的客户端。
我们通过指定“/app”前缀来过滤目标应用程序注释方法(通过@MessageMapping )来完成我们的 简单配置。
registerStompEndpoints方法注册“ /chat”端点,启用Spring 的STOMP支持。请记住,为了弹性起见,我们还在此处添加了一个无需 SockJS 即可工作的端点。
当此端点以“/app”为前缀时,它是ChatController.send()方法映射到句柄的端点。
它还启用了SockJS后备选项 ,以便在 WebSocket 不可用时可以使用替代消息传递选项。这很有用,因为并非所有浏览器都支持 WebSocket,并且可能会受到限制性网络代理的阻止。
回退让应用程序可以使用 WebSocket API,但在运行时需要时可以优雅地降级为非 WebSocket 替代方案。
2.创建消息模型
现在我们已经设置了项目并配置了 WebSocket 功能,我们需要创建一条要发送的消息。
端点将接受包含发送者名称和 STOMP 消息中文本的消息,该消息的正文是JSON对象。
该消息可能如下所示:
{ "from": "John", "text": "Hello!" }
为了对携带文本的消息进行建模,我们可以创建一个带有from和text 属性的简单Java 对象:
public class Message { private String from; private String text; // getters and setters }
默认情况下,Spring 将使用Jackson库将我们的模型对象与 JSON 相互转换。
3.创建消息处理控制器
正如我们所看到的,Spring 使用 STOMP 消息传递的方法是将控制器方法关联到配置的端点。我们可以通过@MessageMapping注解来做到这一点。
端点和控制器之间的关联使我们能够在需要时处理消息:
@MessageMapping("/chat") @SendTo("/topic/messages") public OutputMessage send(Message message) throws Exception { String time = new SimpleDateFormat("HH:mm").format(new Date()); return new OutputMessage(message.getFrom(), message.getText(), time); }
在我们的示例中,我们将创建另一个名为OutputMessage的模型对象来表示发送到配置的目的地的输出消息。我们用发件人以及从传入消息中获取的消息文本填充对象,并使用时间戳对其进行丰富。
处理消息后,我们将其发送到使用@SendTo注释定义的适当目的地。“ /topic/messages ”目的地的所有订阅者都将收到该消息。
4.创建浏览器客户端
在服务器端进行配置后,我们将使用sockjs-client库构建一个与消息系统交互的简单 HTML 页面。
首先,我们需要导入sockjs和stomp JavaScript 客户端库。
接下来,我们可以创建一个connect()函数来打开与端点的通信,一个sendMessage()函数来发送我们的 STOMP 消息,以及一个disconnect()函数来关闭通信:
<html> <head> <title>Chat WebSocket</title> <script src="resources/js/sockjs-0.3.4.js"></script> <script src="resources/js/stomp.js"></script> <script type="text/javascript"> var stompClient = null; function setConnected(connected) { document.getElementById('connect').disabled = connected; document.getElementById('disconnect').disabled = !connected; document.getElementById('conversationDiv').style.visibility = connected ? 'visible' : 'hidden'; document.getElementById('response').innerHTML = ''; } function connect() { var socket = new SockJS('/chat'); stompClient = Stomp.over(socket); stompClient.connect({}, function(frame) { setConnected(true); console.log('Connected: ' + frame); stompClient.subscribe('/topic/messages', function(messageOutput) { showMessageOutput(JSON.parse(messageOutput.body)); }); }); } function disconnect() { if(stompClient != null) { stompClient.disconnect(); } setConnected(false); console.log("Disconnected"); } function sendMessage() { var from = document.getElementById('from').value; var text = document.getElementById('text').value; stompClient.send("/app/chat", {}, JSON.stringify({'from':from, 'text':text})); } function showMessageOutput(messageOutput) { var response = document.getElementById('response'); var p = document.createElement('p'); p.style.wordWrap = 'break-word'; p.appendChild(document.createTextNode(messageOutput.from + ": " + messageOutput.text + " (" + messageOutput.time + ")")); response.appendChild(p); } </script> </head> <body onload="disconnect()"> <div> <div> <input type="text" id="from" placeholder="Choose a nickname"/> </div> <br /> <div> <button id="connect" onclick="connect();">Connect</button> <button id="disconnect" disabled="disabled" onclick="disconnect();"> Disconnect </button> </div> <br /> <div id="conversationDiv"> <input type="text" id="text" placeholder="Write a message..."/> <button id="sendMessage" onclick="sendMessage();">Send</button> <p id="response"></p> </div> </div> </body> </html>
5.其他
@EnableWebSocket注释用于配置 Web 套接字请求的处理。可以通过实现WebSocketConfigurer类来完成自定义:
@Configuration @EnableWebSocket public class MyConfiguration implements WebSocketConfigurer { @Override public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { registry.addHandler(echoWebSocketHandler(), "/echo").withSockJS(); } @Bean public WebSocketHandler echoWebSocketHandler() { return new EchoWebSocketHandler(); } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端