• 【WebSocket】一个简单的前后端交互Demo


     WebSocket资料参考:

    https://www.jianshu.com/p/d79bf8174196 

    使用SpringBoot整合参考:

    https://blog.csdn.net/KeepStruggling/article/details/105543449
    

      

    后端部分:

    直接使用Springboot,依赖只有内嵌tomcat和对应的websocket封装启动包

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.1.3.RELEASE</version>
        </parent>
    
        <groupId>cn.cloud9</groupId>
        <artifactId>WebSocket</artifactId>
        <version>1.0-SNAPSHOT</version>
    
        <properties>
            <maven.compiler.source>8</maven.compiler.source>
            <maven.compiler.target>8</maven.compiler.target>
        </properties>
    
        <dependencies>
            <!-- 内嵌Tomcat库来提供WebSocketAPI -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
    
            <!-- Spring对WebSocket的扩展Starter -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-websocket</artifactId>
            </dependency>
        </dependencies>
    
    </project>
    

      

    定义WebSocket接口

    package cn.cloud9.endpoint;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.stereotype.Component;
    
    import javax.websocket.*;
    import javax.websocket.server.ServerEndpoint;
    import java.io.IOException;
    import java.util.Map;
    import java.util.concurrent.ConcurrentHashMap;
    
    /**
     * @author OnCloud9
     * @description
     * @project WebSocket
     * @date 2022年06月15日 20:13
     *
     * ws://localhost:8080/ws/test
     */
    @Component
    @ServerEndpoint("/ws/test")
    public class TestEndpoint {
        private static final Logger LOGGER = LoggerFactory.getLogger(TestEndpoint.class);
    
        private static final Map<String, Session> CLIENT_SESSION_MAP = new ConcurrentHashMap<>();
    
        /**
         * 侦测客户端向此服务建立连接,此终端实例会新创建出来
         * @param session
         */
        @OnOpen
        public void onOpen(Session session) {
            LOGGER.info("客户端 {} 开启了连接", session.getId());
            // 默认按照ID保管存放这个客户端的会话信息
            CLIENT_SESSION_MAP.put(session.getId(), session);
        }
    
        /**
         * 侦测客户端异常
         * @param session
         * @param error
         */
        @OnError
        public void onError(Session session, Throwable error) {
            LOGGER.info("客户端 {} 连接异常... 异常信息:{}", session.getId(), error.getMessage());
            LOGGER.error(error.getMessage());
        }
    
        /**
         * 侦测客户端向此服务端发送消息
         * @param session
         * @param message
         */
        @OnMessage
        public void onMessage(Session session, String message) {
            // 可根据会话ID或者message中自定义唯一标识从容器中取出会话对象来进行操作
            LOGGER.info("收到消息, 来自客户端 {}, 消息内容 -> {}", session.getId(), message);
        }
    
        /**
         * 侦测客户端关闭事件
         * @param session
         */
        @OnClose
        public void onClose(Session session) {
            LOGGER.info("客户端 {} 关闭了连接...", session.getId());
            // 客户端关闭时,从保管容器中踢出会话
            CLIENT_SESSION_MAP.remove(session.getId());
        }
    
        /**
         * 给所有客户端发送消息
         * @param message
         */
        public static void sendMessageForAllClient(String message) {
            CLIENT_SESSION_MAP.values().forEach(session -> {
                try {
                    LOGGER.info("给客户端 {} 发送消息 消息内容: {}", session.getId(), message);
                    session.getBasicRemote().sendText(message);
                } catch (IOException e) {
                    e.printStackTrace();
                    LOGGER.info("给客户端 {} 发送消息失败, 异常信息:{}", session.getId(), e.getMessage());
                }
            });
        }
    
    
    }
    

    配置WebSocket接口暴露器

    package cn.cloud9.config;
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.socket.server.standard.ServerEndpointExporter;
    
    /**
     * @author OnCloud9
     * @description
     * @project WebSocket
     * @date 2022年06月15日 20:42
     */
    @Configuration
    public class WebSocketConfig {
        /**
         * 如果使用Springboot默认内置的tomcat容器,则必须注入ServerEndpoint的bean;
         * 如果使用外置的web容器,则不需要提供ServerEndpointExporter,下面的注入可以注解掉
         */
        @Bean
        public ServerEndpointExporter serverEndpointExporter(){
            return new ServerEndpointExporter();
        }
    }
    

      

    写一个Controller,通过一般Http接口向WebSocket客户端推送消息

    package cn.cloud9.controller;
    
    import cn.cloud9.endpoint.TestEndpoint;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.RestController;
    
    /**
     * @author OnCloud9
     * @description
     * @project WebSocket
     * @date 2022年06月15日 20:46
     */
    @RestController
    @RequestMapping("/api/ws")
    public class WebSocketController {
    
        /**
         * http://localhost:8080/api/ws/send
         * @param message
         * @return
         */
        @GetMapping("/send")
        public boolean send(@RequestParam String message) {
            TestEndpoint.sendMessageForAllClient(message);
            return true;
        }
    }
    

      

    前端页面:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>WebSocket 页面客户端</title>
    </head>
    <body>
    
    <div>
        <button onclick="initConnection()">开启WebSocket连接</button>
    </div>
    <div>
        <input type="text" id="message" ><button onclick="sendMessageFromClient()">发送消息</button>
    </div>
    
    <div>
        <button onclick="closeConnection()">关闭连接</button>
    </div>
    
    <script>
        const connectionUrl = 'ws://localhost:8080/ws/test'
        var webSocket = null
    
        function initConnection() {
            webSocket = new WebSocket(connectionUrl)
    
            webSocket.onopen = (event) => {
                console.log('建立新的WebSocket连接')
            }
    
            webSocket.onmessage = (event) => {
                const message = JSON.stringify(event.data)
                console.log(`收到服务端发送的消息,消息内容 -> ${message}`)
            }
    
            webSocket.onerror = (error) => {
                console.log(`WebSocket连接异常 -> ${JSON.stringify(error)}`)
            }
    
            webSocket.onclose = (event) => {
                console.log(`WebSocket连接关闭 -> ${JSON.stringify(event)}`)
            }
        }
    
        function sendMessageFromClient() {
            const message = document.querySelector('#message').value
            webSocket.send(JSON.stringify({ message: message }))
        }
    
        function closeConnection() {
            webSocket.close()
        }
    </script>
    </body>
    </html>
    

      

      

  • 相关阅读:
    day⑥:logging模块
    day⑥:shelve模块
    day⑥:xml模块
    day⑤:冒泡排序
    day⑤:模块
    day⑤:re深入
    day④:递归
    day④:迭代器
    day④:装饰器
    day③:函数式编程
  • 原文地址:https://www.cnblogs.com/mindzone/p/16379941.html
Copyright © 2020-2023  润新知