美文网首页JavaSpringBoot
SpringBoot实现websocket实现聊天

SpringBoot实现websocket实现聊天

作者: 花伤情犹在 | 来源:发表于2022-03-26 14:00 被阅读0次

Maven依赖:

         <!--screw依赖-->
        <dependency>
            <groupId>cn.smallbun.screw</groupId>
            <artifactId>screw-core</artifactId>
            <version>1.0.2</version>
        </dependency>
        <!--hutools-->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.7.12</version>
        </dependency>
        <!--javaee-api-->
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-api</artifactId>
            <version>7.0</version>
            <scope>provided</scope>
        </dependency>
        <!--json-lib-->
        <dependency>
            <groupId>net.sf.json-lib</groupId>
            <artifactId>json-lib</artifactId>
            <version>2.4</version>
            <classifier>jdk15</classifier>
        </dependency>
        <!--websocket-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
        </dependency>

在线模拟websocket请求工具:
https://www.bejson.com/httputil/websocket/

websocketConfig:


/**
 * websocket配置
 */
@Configuration
public class websocketConfig {
    /**
     * 服务器端点导出器
     * @return
     */
    @Bean
    public ServerEndpointExporter serverEndpointExporter(){
        return new ServerEndpointExporter();
    }
}

WebSocketOneToOne:

/**
 * @ServerEndpoint 注解是一个类层次的注解,它的功能主要是将目前的类定义成一个websocket服务器端,
 *                 注解的值将被用于监听用户连接的终端访问URL地址,客户端可以通过这个URL来连接到WebSocket服务器端
 */
@RestController
@ServerEndpoint(value = "/webSocketOneToOne/{param}")
public class WebSocketOneToOne {

    // 静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
    private static int onlineCount;
    //实现服务端与单一客户端通信的话,可以使用Map来存放,其中Key为用户标识
    private static Map<String,WebSocketOneToOne> connections = new ConcurrentHashMap<>();
    // 与某个客户端的连接会话,需要通过它来给客户端发送数据
    private Session session;
    //角色
    private String role;
    //socketid
    private String socketId;

    /**
     * 连接建立成功调用的方法
     *
     * @param session
     *            可选的参数。session为与某个客户端的连接会话,需要通过它来给客户端发送数据
     */
    @OnOpen
    public void onOpen(@PathParam("param") String param, Session session) {
        this.session = session;
        String[] arr = param.split(",");
        this.role = arr[0];             //用户标识
        this.socketId = arr[1];         //会话标识
        connections.put(role,this);     //添加到map中
        addOnlineCount();               // 在线数加
        System.out.println("有新连接加入!新用户:"+role+",当前在线人数为" + getOnlineCount());
    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose() {
        connections.remove(role);  // 从map中移除
        subOnlineCount();          // 在线数减
        System.out.println("有一连接关闭!当前在线人数为" + getOnlineCount());
    }

    /**
     * 收到客户端消息后调用的方法
     *
     * @param message
     *            客户端发送过来的消息
     * @param session
     *            可选的参数
     */
    @OnMessage
    public void onMessage(String message, Session session) {
        System.out.println("来自客户端的消息:" + message);
        JSONObject json=JSONObject.fromObject(message);
        String string = null;  //需要发送的信息
        String to = null;      //发送对象的用户标识
        if(json.has("message")){
            string = (String) json.get("message");
        }
        if(json.has("role")){
            to = (String) json.get("role");
        }
        send(string,role,to,socketId);
    }

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


    //发送给指定角色
    public void send(String msg,String from,String to,String socketId){
        try {
            //to指定用户
            WebSocketOneToOne con = connections.get(to);
            if(con!=null){
                if(socketId==con.socketId||con.socketId.equals(socketId)){
                    con.session.getBasicRemote().sendText(from+"说11:"+msg);
                }

            }
            //from具体用户
            WebSocketOneToOne confrom = connections.get(from);
            if(confrom!=null){
                if(socketId==confrom.socketId||confrom.socketId.equals(socketId)){
                    confrom.session.getBasicRemote().sendText(from+"说:"+msg);
                }

            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    /**
     * 获取在线人数
     * @return
     */
    public static synchronized int getOnlineCount() {
        return onlineCount;
    }

    /**
     * 在线数添加
     */
    public static synchronized void addOnlineCount() {
        WebSocketOneToOne.onlineCount++;
    }

    public static synchronized void subOnlineCount() {
        WebSocketOneToOne.onlineCount--;
    }
}

用户1

连接请求:

ws://127.0.0.1:8888/webSocketOneToOne/1,520

JSON消息内容:

{ 'message': '2号用户你好', 'role': '2', 'socketId': '520' }

用户2

连接请求:

ws://127.0.0.1:8888/webSocketOneToOne/2,520

JSON消息内容:

{ 'message': '1号用户你好', 'role': '1', 'socketId': '520' }

理解性

message:需要发送的消息内容
role:需要发送的对象
socketId:需要发送的房间

相关文章

网友评论

    本文标题:SpringBoot实现websocket实现聊天

    本文链接:https://www.haomeiwen.com/subject/juedjrtx.html