springboot websocket-元一软件

未分类2个月前发布 元一软件
122 0

1、概览

本文将带你学习如何使用 Spring 4 中引入的 WebSocket 功能来实现一个简单的聊天应用。

Java(编程语言)

WebSockets 是 Web 浏览器和服务器之间的一种双向、全双工、持久连接。一旦建立了 WebSocket 连接,该连接就会一直打开,直到客户端或服务器关闭该连接。

2、Maven 依赖

在 pom.xml 中添加所需的依赖:

<dependency>

    <groupId>org.springframework</groupId>

    <artifactId>spring-websocket</artifactId>

    <version>5.2.2.RELEASE</version>

</dependency>



<dependency>

    <groupId>org.springframework</groupId>

    <artifactId>spring-messaging</artifactId>

    <version>5.2.2.RELEASE</version>

</dependency>

此外,还需要添加 Jackson 依赖,用于序列化/反序列化 JSON 格式的消息。

<dependency>

    <groupId>com.fasterxml.jackson.core</groupId>

    <artifactId>jackson-core</artifactId>

    <version>2.10.2</version>

</dependency>



<dependency>

    <groupId>com.fasterxml.jackson.core</groupId>

    <artifactId>jackson-databind</artifactId> 

    <version>2.10.2</version>

</dependency>

3、启用 WebSocket

首先,在配置类上通过 @EnableWebSocketMessageBroker 注解来启用 WebSocket 功能。

配置类需要继承 AbstractWebSocketMessageBrokerConfigurer。

顾名思义,它能在 Message Broker 的支持下处理 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 方法配置 Message Broker。

首先,启用了一个基于内存的 Message Broker,用于将消息返回给以 /topic 为前缀的客户端目标。

设置应用目标(通过 @MessageMapping 注解的方法)的前缀为 /app。

registerStompEndpoints 方法注册了/chat 端点,从而启用了 Spring 的 STOMP 支持。这里为了提高灵活性,还添加了 SockJS 的支持,但是本文不会使用。

开发工具

该端点(前缀为 /app 时)是 ChatController.send() 方法映射处理的端点。

启用 SockJS 回退选项,以便在无法使用 WebSockets 时使用其他消息传递选项。这一点非常有用,因为 WebSocket 在某些浏览器中尚未得到支持,并且可能受到限制性网络代理的阻止。

当需要时,回退功能允许应用在运行时优雅地降级到非 WebSocket 的替代方案,同时仍然可以使用 WebSocket API。

4、创建 Message Model

配置好 WebSocket 后,创建要发送的消息。

端点接受包含发送人和文本的 STOMP 消息,该消息是一个 JSON 对象。

{

    "from": "John",

    "text": "Hello!"

}

其对应的 Model 类如下:

public class Message {



    private String from;

    private String text;



    // get、set 省略

}

默认情况下,Spring 使用 Jackson 将 Model 对象转换为 JSON 或从 JSON 转换为 Model 对象。

Java(编程语言)

5、创建消息处理 Controller

如你所见,Spring 处理 STOMP 消息的方法是将 Controller 方法与配置的端点关联起来。

可以通过 @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 的 Model 对象来表示发送到配置目的地的输出消息,并在对象中填充发件人(sender)和从传入消息中提取的消息内容,以及一个时间戳。

处理完消息后,会将其发送到使用 @SendTo 注解定义的适当目的地。/topic/messages 目标的所有订阅者都将收到该消息。

6、创建浏览器客户端

服务器配置完毕后,使用 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>

7、测试

为了测试,可以多打开几个浏览器窗口并访问聊天页面:

编程

输入昵称并点击连接按钮后,就可以加入聊天了。此时撰写并发送一条消息,就可以在所有已加入聊天的浏览器会话中看到它。

效果如下:

springboot websocket-元一软件

8、总结

本文介绍了 Spring 的 WebSocket 支持,以及如何使用 sockjs 和 stomp  JavaScript 库构建了一个简单的客户端应用。


Ref:https://www.baeldung.com/websockets-spring

© 版权声明