第十篇:Spring Boot整合WebSocket

版权声明:本文为博主原创文章,欢迎转载,转载请注明作者、原文超链接 ,博主地址:https://blog.csdn.net/mr_chenjie_c。 https://blog.csdn.net/Mr_Chenjie_C/article/details/84956454

WebSocket是通过一个Socket来实现双工异步通信的。直接使用WebSocket或者SockJS协议显得特别繁琐。使用它的子协议STOMP,它是一个更高级别的协议,STOMP协议使用一个基于帧格式来定义消息,与HTTP的Request和Response类似。

环境依赖

Spring Boot对使用WebSocket提供了支持,配置源码在org.springframework.boot.autoconfigure.websocket包下。

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

顺便说一句,springboot的高级组件会自动引用基础的组件,像spring-boot-starter-websocket就引入了spring-boot-starter-web和spring-boot-starter,所以不要重复引入。

配置Websocket

@Configuration
public class WebSocketConfig {
    @Bean
    public ServerEndpointExporter serverEndpointExporter (){
        return new ServerEndpointExporter();
    }
}

处理WebSocket

@ServerEndpoint("/websocket")
@Component
public class WebSocketService {

    private final Logger log = LoggerFactory.getLogger(this.getClass());

    private static int COUNT = 0;

    private static CopyOnWriteArraySet<WebSocketService> websocket = new CopyOnWriteArraySet<WebSocketService>();

    private Session session;

    /*
    建立连接的时候调用
     */
    @OnOpen
    public void onOpen(Session session) {
        this.session = session;
        websocket.add(this);
        addOnlineCount();
        log.info("当前在线人数:" + COUNT);
        try {
            sendMessage("连接成功");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @OnClose
    public void onclose() {
        websocket.remove(this);
        subOnlineCount();
        log.info("有一连接关闭!当前在线人数为" + getOnlineCount());
    }

    /*
    接收到客户端的信息
     */
    @OnMessage
    public void shoudaoMessage(String message, Session session) {
        log.info("server 收到的信息是:" + message);
        //群发消息
        for (WebSocketService item : websocket) {
            try {
                item.sendMessage(message);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 发生错误时调用
     */
    @OnError
    public void onError(Session session, Throwable error) {
        log.error("发生错误");
        error.printStackTrace();
    }


    public void sendMessage(String message) throws IOException {
        this.session.getBasicRemote().sendText(message);
    }


    /**
     * 群发自定义消息
     */
    public static void sendInfo(String message) throws IOException {
        for (WebSocketService item : websocket) {
            try {
                item.sendMessage(message);
            } catch (IOException e) {
                continue;
            }
        }
    }

    public static synchronized int getOnlineCount() {
        return COUNT;
    }

    public static synchronized void addOnlineCount() {

        WebSocketService.COUNT++;
    }

    public static synchronized void subOnlineCount() {
        WebSocketService.COUNT--;
    }
}

新建HTML文件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8"/>
    <title>Title</title>
</head>
<body>
<input id="text" type="text" /><button onclick="send()">Send</button>
<button onclick="closeWebSocket()">Close</button>
<div id="message">
</div>
</body>
<script>
    var websocket = null;
    if('WebSocket' in window){
        websocket = new WebSocket("ws://localhost:8080/websocket");
        // 建立成功后的回调函数
        websocket.onopen = function (ev) {
            setMessageInnerHTML("open");
        }
        websocket.onclose=function(){
            setMessageInnerHTML("close");
        }
        websocket.onmessage=function (ev) {
            setMessageInnerHTML(ev.data);
        }
        //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
        window.onbeforeunload = function(){
            websocket.close();
        }

    }else {
        alert("浏览器不支持");
    }
    //将消息显示在网页上
    function setMessageInnerHTML(innerHTML){
        document.getElementById('message').innerHTML += innerHTML + '<br/>';
    }

    //关闭连接
    function closeWebSocket(){
        websocket.close();
    }

    //发送消息
    function send(){
        var message = document.getElementById('text').value;
        websocket.send(message);
    }
</script>
</html>

服务器推送

@RestController
public class WebSocketSendMessageController {
    @Autowired
    private WebSocketService socketService;
    @GetMapping("/send")
    public String sendMessage(){
        try {
            socketService.sendInfo("大家好");
        } catch (IOException e) {
            e.printStackTrace();
            return "fail";
        }
        return "succcess";
    }
}

测试

用浏览器打开刚刚新建的html文件
在这里插入图片描述
可以在多个窗口打开,看看控制台日志信息
在这里插入图片描述

发送消息
在这里插入图片描述
在这里插入图片描述

服务器推送消息
在这里插入图片描述
在这里插入图片描述
可以看到客户端接受到了消息

源码下载:https://github.com/chenjary/SpringBoot

猜你喜欢

转载自blog.csdn.net/Mr_Chenjie_C/article/details/84956454
今日推荐