配置好maven项目的依赖
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-websocket</artifactId>
</dependency>

1. MySpringConfigurator 配置类

以websocketConfig.java注册的bean是由自己管理的,需要使用配置托管给spring管理
package com.xbr.common.config;

/**
 * @author dhn
 * @description
 * @date 2021/1/23 0023
 */


import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

import javax.websocket.server.ServerEndpointConfig;

/**
 *  以websocketConfig.java注册的bean是由自己管理的,需要使用配置托管给spring管理
 */
public class MySpringConfigurator extends ServerEndpointConfig.Configurator implements ApplicationContextAware {

    private static volatile BeanFactory context;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        MySpringConfigurator.context = (BeanFactory) applicationContext;
    }

    @Override
    public <T> T getEndpointInstance(Class<T> clazz) throws InstantiationException {
        return context.getBean(clazz);
    }
}

2.WebSocketConfig

socket配置类
package com.xbr.common.config;

/**
 * @author dhn
 * @description socket配置类
 * @date 2021/1/23 0023
 */
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;

@Configuration
public class WebSocketConfig {
    /**
     * ServerEndpointExporter 作用
     *
     * 这个Bean会自动注册使用@ServerEndpoint注解声明的websocket endpoint
     *
     * @return
     */

    //使用boot内置tomcat时需要注入此bean
    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }

    @Bean
    public MySpringConfigurator mySpringConfigurator() {
        return new MySpringConfigurator();
    }
}

3.WebSocket 核心类

package com.xbr.common.test;


import com.alibaba.fastjson.JSONObject;
import com.xbr.common.config.MySpringConfigurator;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author dhn
 * @description WebSocketServer核心类
 * @date 2021/1/18 0018
 */

/*
    websocket所需注解,设置监听路径等,此注解会为每一个连接请求创建一个point实例对象,
    此注解会将编解码成一个websocket服务,url是发布路径。
 */
@Component
@ServerEndpoint(value ="/webSocket/{sid}" , configurator = MySpringConfigurator.class)
public class WebSocketServer {

    //静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
    private static AtomicInteger onlineNum = new AtomicInteger();

    //concurrent包的线程安全Set,用来存放每个客户端对应的WebSocketServer对象。
    private static ConcurrentHashMap<String, Session> sessionPools = new ConcurrentHashMap<>();

    /**
     * 线程安全list,用来存放 在线客户端账号
     */
    public static List<String> userList = new CopyOnWriteArrayList<>();

    //发送消息
    public void sendMessage(Session session, String message) throws IOException {
        if (session != null) {
            synchronized (session) {
//                System.out.println("发送数据:" + message);
                session.getBasicRemote().sendText(message);
            }
        }
    }

    //给指定用户发送信息
    public void sendInfo(String userName, String message) {
        Session session = sessionPools.get(userName);
        try {
            sendMessage(session, message);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //建立连接成功调用
    @OnOpen
    public void onOpen(Session session, @PathParam(value = "sid") String userName) {
        sessionPools.put(userName, session);
        addOnlineCount();
        userList.add(userName);
        System.out.println(userName + "加入webSocket!当前人数为" + onlineNum);
        System.out.println("当前在线:" + userList);
        try {
            sendMessage(session, "欢迎" + userName + "加入连接!");

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //关闭连接时调用
    @OnClose
    public void onClose(@PathParam(value = "sid") String userName) {
        sessionPools.remove(userName);
        userList.remove(userName);

        subOnlineCount();
        System.out.println(userName + "断开webSocket连接!当前人数为" + onlineNum);

    }

    //收到客户端信息
    @OnMessage
    public void onMessage(String message) throws IOException {
//        message = "客户端:" + message + ",已收到";
        JSONObject jsonObject = JSONObject.parseObject(message);
        String touser = jsonObject.get("toUserId").toString();
        String text =jsonObject.get("contentText").toString();
        System.out.println(message);
        sendInfo(touser,text);
//        for (Session session : sessionPools.values()) {
//            try {
//                sendMessage(session, message);
//
//            } catch (Exception e) {
//                e.printStackTrace();
//                continue;
//            }
//        }
    }

    //错误时调用
    @OnError
    public void onError(Session session, Throwable throwable) {
        System.out.println("发生错误");
        throwable.printStackTrace();
    }

    public static void addOnlineCount() {
        onlineNum.incrementAndGet();
    }

    public static void subOnlineCount() {
        onlineNum.decrementAndGet();

    }
}

4.配置html页面,定义两个用户页面对话 test.html 和test1.html

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>WebSocket</title>

</head>
<body>
<h3>hello socket</h3>
<div style="float: left">
    <p>【发送者】:<div><input id="userId" name="userId" type="text" value="10"></div>
    <p>【接收者】:<div><input id="toUserId" name="toUserId" type="text" value="20"></div>
    <p>【发送信息】:<div><textarea style="width: 200px;height: 50px" id="contentText" name="contentText" type="text" placeholder="输入发送的信息"></textarea>
    <button onclick="sendMessage()" style="width: 60px;height: 30px;">发送</button>
</div>
    <p>操作:<div><a onclick="openSocket()">开启socket</a></div>
    <p>【操作】:<div><a onclick="Close()">关闭连接</a></div>
</div>
<div id="msg" style="float: left; margin-left: 200px">
</div>
</body>
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script>
    var socket;

    window.onload = function () {
        if(typeof(WebSocket) == "undefined") {
            console.log("您的浏览器不支持WebSocket");
        }else{
            console.log("您的浏览器支持WebSocket");
            //实现化WebSocket对象,指定要连接的服务器地址与端口  建立连接
            var userId = document.getElementById('userId').value;
            // var socketUrl="ws://127.0.0.1:22599/webSocket/"+userId;
            var socketUrl="ws://192.168.1.170:8668/webSocket/"+userId;
            console.log(socketUrl);
            if(socket!=null){
                socket.close();
                socket=null;
            }
            socket = new WebSocket(socketUrl);
            //打开事件
            socket.onopen = function() {
                console.log("websocket已打开");
                //socket.send("这是来自客户端的消息" + location.href + new Date());
            };
            //获得消息事件
            socket.onmessage = function(msg) {
                var serverMsg = "收到信息:" + msg.data;
                console.log(serverMsg);
                var ul =  $("#msg").append("<ul>");
                ul.append("<li>"+ serverMsg +"</li>");
                $("#msg").append("</ul>");
            };
            //关闭事件
            socket.onclose = function() {
                console.log("websocket已关闭");
            };
            //发生了错误事件
            socket.onerror = function() {
                console.log("websocket发生了错误");
            }
        }
    };


    function openSocket() {
        if(typeof(WebSocket) == "undefined") {
            console.log("您的浏览器不支持WebSocket");
        }else{
            console.log("您的浏览器支持WebSocket");
            //实现化WebSocket对象,指定要连接的服务器地址与端口  建立连接
            var userId = document.getElementById('userId').value;
            // var socketUrl="ws://127.0.0.1:22599/webSocket/"+userId;
            var socketUrl="ws://localhost:8668/webSocket/"+userId;
            console.log(socketUrl);
            if(socket!=null){
                socket.close();
                socket=null;
            }
            socket = new WebSocket(socketUrl);
            //打开事件
            socket.onopen = function() {
                console.log("websocket已打开");
                //socket.send("这是来自客户端的消息" + location.href + new Date());
            };
            //获得消息事件
            socket.onmessage = function(msg) {
                var serverMsg = "收到服务端信息:" + msg.data;
                console.log(serverMsg);

                //发现消息进入    开始处理前端触发逻辑
                var ul =  $("#msg").append("<ul>");
                ul.append("<li>"+ serverMsg +"</li>");
                $("#msg").append("</ul>");


            };
            //关闭事件
            socket.onclose = function() {
                console.log("websocket已关闭");
            };
            //发生了错误事件
            socket.onerror = function() {
                console.log("websocket发生了错误");
            }
        }
    }
    function sendMessage() {
        if(typeof(WebSocket) == "undefined") {
            console.log("您的浏览器不支持WebSocket");
        }else {
            // console.log("您的浏览器支持WebSocket");
            var toUserId = document.getElementById('toUserId').value;
            var contentText = document.getElementById('contentText').value;
            var msg = '{"toUserId":"'+toUserId+'","contentText":"'+contentText+'"}';
            var sendMsg = "我发送给"+ toUserId + ",说:"+ contentText
            console.log(msg);
            socket.send(msg);
            //发现消息进入    开始处理前端触发逻辑
            var ul =  $("#msg").append("<ul>");
            ul.append("<li>"+ sendMsg +"</li>");
            $("#msg").append("</ul>");
        }
    }

    function Close() {
        if(typeof(WebSocket) == "undefined") {
            console.log("您的浏览器不支持WebSocket");
        }else {
            // console.log("您的浏览器支持WebSocket");
            var userId = document.getElementById('userId').value;

            var msg = '{"userId":"'+userId+'"}';
            console.log('关闭连接',msg);
            socket.close();
        }
    }

</script>
</html>

 另一个页面调整接收者和发送信息者 其他一样

<p>【发送者】:<div><input id="userId" name="userId" type="text" value="10"></div>
<p>【接收者】:<div><input id="toUserId" name="toUserId" type="text" value="20"></div>

5.完毕,调试成功了,记录一下
效果展示

springboot j即时聊天 springboot一对一聊天_spring

springboot j即时聊天 springboot一对一聊天_spring_02