WebSocket+SpringBoot的小Demo记录

gitee地址: https://gitee.com/equinox166/simple-online-chat

前端:html

核心代码:

socket.onopen = function() {}

用户连接时触发

socket.onmessage = function(e) {}

接收到服务器端传来的信息时触发

socket.onerror = function() {}

连接错误时触发

socket.onclose = function() {}

关闭连接时触发

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>websocket通讯</title>
    <style type="text/css">
        #ad,#bd {
            width: 300px;
            height: 200px;
            border: solid 1px;
            }
    </style>
</head>
<body>
    <script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>

    <!-- 用户一:tom  -->
    <div>
        <input id="ai" type="text" placeholder="请输入">
        <button id="ab">发送</button>
        <div id="ad"></div>
    </div>
    <script>
        var inputa = document.querySelector('#ai')
        var buttona = document.querySelector('#ab')
        var diva = document.querySelector('#ad')        
        var chat = {
                username : 'tom',
                message : '连接'
            }
        var url = 'ws://127.0.0.1:9090/WebSocketLink/{'+ JSON.stringify(chat) +'}'
        var socketa = new WebSocket(url)
        socketa.onopen = function() {
            diva.innerHTML = diva.innerText + '连接成功'
        }
        $('#ab').click(function(){
            var msg = $('#ai').val()
            $('#ai').val("")
            var chat = {
                username : 'tom',
                message : msg
            }
            socketa.send(JSON.stringify(chat))
        })
        socketa.onmessage = function(e) {
            var chat = e.data
            diva.innerHTML = diva.innerText +'/n' +  JSON.parse(chat).message
        }
        socketa.onerror = function() {
            diva.innerHTML = diva.innerText + '<br>连接失败'
        }
        socketa.onclose = function() {
            div.innerHTML = diva.innerText + '<br>连接关闭'
        }
    </script>

    <!-- 用户二:jerry -->
    <div>
        <input id="bi" type="text" placeholder="请输入">
        <button id="bb">发送</button>
        <div id="bd"></div>
    </div>
    <script>
        var inputb = document.querySelector('#bi')
        var buttonb = document.querySelector('#bb')
        var divb = document.querySelector('#bd')
        var chat = {
                username : 'jerry',
                message : '连接'
            }
        var url = 'ws://127.0.0.1:9090/WebSocketLink/{'+ JSON.stringify(chat) +'}'
        var socketb = new WebSocket(url)
        socketb.onopen = function() {
            divb.innerHTML = divb.innerText + '连接成功'
        }
        $('#bb').click(function(){
            var msg = $('#bi').val()
            $('#bi').val("")
            var chat = {
                username : 'jerry',
                message : msg
            }
            socketa.send(JSON.stringify(chat))
        })
        socketb.onmessage = function(e) {
            var chat = e.data
            divb.innerHTML = divb.innerText +'/n' +  JSON.parse(chat).message
        }
        socketb.onerror = function() {
            divb.innerHTML = divb.innerText + '<br>连接失败'
        }
        socketb.onclose = function() {
            divb.innerHTML = divb.innerText + '<br>连接关闭'
        }
    </script>
</body>
</html>

写了两个div分别放两个用户,用户信息写死tom和jerry。

使用时直接改chat对象就可以了。

后端:SpringBoot

maven导入:web启动器、webSocket、lombok和JSON工具类依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
</dependency>
<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-json</artifactId>
    <version>5.4.7</version>
</dependency>

ChatServer服务器端代码

ConcurrentHashMap用来存放连接上的用户信息

onLineCount用来计用户数

@onOpen注解表示此方法在用户连接时触发

@onMessage注解表示服务器每次接收到来自用户端的信息时触发

@onClose注解表示每次用户断开连接时触发

@onError注解表示用户连接发生错误时触发

@ServerEndpoint("/WebSocketLink/{userInfo}")
@Component
public class ChatServer {
    private static ConcurrentHashMap<String, Chat> map = new ConcurrentHashMap<>();
    private static int onLineCount = 0;
    @OnOpen
    public void onOpen(Session session, @PathParam("userInfo") String userInfo ) {
        System.out.println(session);
        System.out.println("有用户连接上来了");
        System.out.println(userInfo);
        Chat chat = JSONUtil.toBean(userInfo, Chat.class);
        chat.setSession(session);
        System.out.println(chat);
        map.put(chat.getUsername(),chat);
    }

    @OnMessage
    public void onMessage(String message) throws IOException {
        System.out.println(message);
        Chat chat = JSONUtil.toBean(message, Chat.class);
        System.out.println(chat);
        String username = "tom";
        if(chat.getUsername().equals("tom")){
            username = "jerry";
        }
        map.get(username).getSession().getBasicRemote().sendText(JSONUtil.toJsonStr(chat));
    }

    @OnClose
    public void onClose() { }

    @OnError
    public void one rror(Throwable error) {
        error.printStackTrace();
    }

    public static synchronized int getOnLineCount(){
        return onLineCount;
    }

    public static synchronized void addOnLineCount(){
        onLineCount++;
    }

    public static synchronized void subOnLineCount(){
        onLineCount--;
    }

}

WebSocketConfig配置类代码

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

Chat实体类代码

@Data
@EqualsAndHashCode(callSuper = false)
public class Chat {
    String username;
    String message;
    Session session;
}
上一篇:Redis04——发布订阅模式


下一篇:javascript – 在Firebase中管理聊天频道的最佳方式