随笔 - 141,  文章 - 0,  评论 - 10,  阅读 - 16万

1、新建WebSocketConfig配置类

复制代码
package com.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;

@Configuration
public class WebSocketConfig {
    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }
}
复制代码

2、新建具体业务socket

复制代码
package com.socket;

import lombok.extern.slf4j.Slf4j;
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.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;

@ServerEndpoint("/sysMessageSocket/{token}")
@Component
@Slf4j
public class SysMessageWebSocket {
    private Session session;
    private static ConcurrentHashMap<String, Session> sessionPool = new ConcurrentHashMap<>();
    private static CopyOnWriteArraySet<SysMessageWebSocket> webSocketSet = new CopyOnWriteArraySet<>();

    @OnOpen
    public void onOpen(Session session, @PathParam(value = "token") String token) {
        log.info("WebSocket建立连接中,连接用户ID:{}", token);
        try {
            Session historySession = sessionPool.get(token);
            if (historySession != null) {
                webSocketSet.remove(historySession);
                historySession.close();
            }
        } catch (IOException e) {
            log.error("重复登录异常,错误信息:" + e.getMessage(), e);
        }
        this.session = session;
        webSocketSet.add(this);
        sessionPool.put(token, session);
        log.info("建立连接完成,当前在线人数为:{}", webSocketSet.size());
    }

    @OnError
    public void onError(Throwable throwable) {
        throwable.printStackTrace();
    }

    @OnClose
    public void onClose() {
        webSocketSet.remove(this);
        String token = this.session.getRequestParameterMap().get("token").get(0);
        log.info(token + "连接断开,当前在线人数为:{}", webSocketSet.size());
    }

    @OnMessage
    public void onMessage(String message) {
        log.info("收到客户端发来的消息:{}", message);
    }

    public void sendMessageByUser(String token, String message) {
        log.info("用户ID:" + token + ",推送内容:" + message);
        Session session = sessionPool.get(token);
        try {
            if(session!=null){
                session.getBasicRemote().sendText(message);
            }else{
                log.info("连接已断开,用户ID:" + token + ",内容推送失败:" + message + "。session为空。");
            }
        } catch (IllegalStateException | IOException e) {
            log.info("连接已断开,用户ID:" + token + ",内容推送失败:" + message + "。"+e.getMessage());
        }
    }

    public void sendAllMessage(String message) {
        log.info("发送消息:{}", message);
        for (SysMessageWebSocket webSocket : webSocketSet) {
            try {
                webSocket.session.getBasicRemote().sendText(message);
            } catch (IOException e) {
                log.error("群发消息发生错误:" + e.getMessage(), e);
            }
        }
    }

}
复制代码

3、测试

通过 www.jsons.cn/websocket/ 测试本地socket是否互通

注意:

config配置文件WebSocketConfig的ServerEndpointExporter(服务器端点导出器)与@Test冲突(websocket是需要依赖tomcat等容器的启动)

方案:本地启用测试代码时需要将@Bean注掉(提交git的代码需要将Test代码注掉);

  新建测试类时,在springbootTest后添加内容webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT。

例如测试类为

复制代码
package com.test;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest(classes = MicroenterpriseApplication.class,webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class VerifyCodeServiceImplTest {

    @Test
    public void getVerifyCode() {
        
    }
}
复制代码

 

posted on   程序员丁先生  阅读(178)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示