web常用技能

使用SpringBoot搭建实时通信服务

2021-10-20  本文已影响0人  向上生长之路

在软件开发过程中,经常需要获取服务器端数据来展示给用户,对于数据的及时性有要求的场景,我们可能会采用长轮询等方式,来以一定的频率向服务器发起请求拉取数据,轮询方式会持续占用系统资源,效率较低,那么有没有一种解决方案,能做到服务器端有数据更新,及时通知客户端呢?通过使用websocket技术,我们可以做到客户端与服务器端的全双工通信,两端都可以实时的发送数据给对方~,下面就给大家介绍下SpringBoot中怎么整合websocket技术

使用方式

1.修改SpringBoot工程中的pom.xml配置,增加websocket的依赖

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
        </dependency>

2.修改SpringBoot工程启动类,添加@EnableWebSocket注解来启用websocket能力支持


3.添加websocket配置
完整代码参考:https://github.com/netbuffer/spring-boot-websocket-demo/blob/master/src/main/java/cn/netbuffer/springboot/websocket/demo/config/SpringWebSocketConfig.java
@Configuration
public class SpringWebSocketConfig implements WebSocketConfigurer {

    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        //添加通信地址路径
        registry.addHandler(buildTextHandler(), "/ws").setAllowedOrigins("*");
    }

    @Bean
    public WebSocketHandler buildTextHandler() {
        //添加消息处理器
        return new TextHandler();
    }

}

4.实现自己的消息处理器
完整代码参考:https://github.com/netbuffer/spring-boot-websocket-demo/blob/master/src/main/java/cn/netbuffer/springboot/websocket/demo/websocket/handler/TextHandler.java

@Slf4j
public class TextHandler extends TextWebSocketHandler {

    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        if (session.isOpen()) {
            log.info("receive websocket message:{} session:{}", message, session.getId());
            TextMessage returnMessage = new TextMessage(message.getPayload() + " received at server");
            session.sendMessage(returnMessage);
        }
    }

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        super.afterConnectionEstablished(session);
        //建立连接后保存WebSocketSession会话
        SessionManager.put(session.getId(), session);
        log.info("session[{}] afterConnectionEstablished", session.getId());
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        log.info("session[{}] afterConnectionClosed", session.getId());
        //释放连接后移除WebSocketSession会话
        SessionManager.remove(session.getId());
    }
}

5.建立Controller控制器层映射方法,来测试主动推送消息到客户端
完整代码参考:https://github.com/netbuffer/spring-boot-websocket-demo/blob/master/src/main/java/cn/netbuffer/springboot/websocket/demo/controller/WebsocketController.java

@RestController
@RequestMapping("/ws")
public class WebsocketController {

    @GetMapping("{session}/send")
    public void send(@PathVariable("session") String session, String msg) {
        WebSocketMessage webSocketMessage = new TextMessage(msg);
        try {
            SessionManager.get(session).sendMessage(webSocketMessage);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

6.编写客户端html代码验证websocket能力
完整代码参考:https://github.com/netbuffer/UItest/blob/master/websocket/index.html

<script type="text/javascript">
    var ws = new WebSocket("ws://localhost:17000/ws");
    ws.onopen = function () {
        console.log("Connection open ...");
    };
    ws.onmessage = function (r) {
        console.log("Received Message: " + r.data);
    };
    ws.onclose = function () {
        console.log("Connection closed.");
    };
</script>
<input name="text" placeholder="请输入文本内容" /><button onclick="ws.send(document.querySelector('input[name=\'text\']').value)">send</button>&emsp;<button onclick="ws.close()">close</button>

运行效果

启动SpringBoot工程,再使用chrome浏览器访问客户端页面,打开开发者工具



观察开发者工具控制台已经打印出连接的日志,服务器端控制台也已经打印出连接日志
现在通过客户端页面发送一些消息,来查看服务器端日志是否有输出~



观察结果可以看到服务器端已经收到对应内容,并写回响应消息给客户端了

再测试下服务器主动推送消息给客户端的效果,使用Postman工具访问我们编写的接口来发送一些消息给客户端,注意session字符串可以从服务器日志打印中找到

GET /ws/73f67e83-79f5-a238-844f-c80f6926a429/send?msg=你好 HTTP/1.1
Host: localhost:17000

观察结果可以看到服务器已经能实时推送相应的内容给客户端了~

完整测试工程参考:https://github.com/netbuffer/spring-boot-websocket-demo

上一篇 下一篇

猜你喜欢

热点阅读