首页 > 其他分享 >springboot集成socketio

springboot集成socketio

时间:2024-06-12 17:21:22浏览次数:14  
标签:集成 springboot socketio void private sessionId configuration public

1.引入依赖

<dependency>
  <groupId>com.corundumstudio.socketio</groupId>
  <artifactId>netty-socketio</artifactId>
  <version>2.0.3</version>
 </dependency>

2.基本配置

server:
  port: 8081
socketio:
  host: localhost
  port: 9091
  # 设置最大每帧处理数据的长度,防止他人利用大数据来攻击服务器
  maxFramePayloadLength: 1048576
  # 设置http交互最大内容长度
  maxHttpContentLength: 1048576
  # socket连接数大小(如只监听一个端口boss线程组为1即可)
  bossCount: 1
  workCount: 100
  allowCustomRequests: true
  # 协议升级超时时间(毫秒),默认10秒。HTTP握手升级为ws协议超时时间
  upgradeTimeout: 10000
  # Ping消息超时时间(毫秒),默认60秒,这个时间间隔内没有接收到心跳消息就会发送超时事件
  pingTimeout: 60000
  # Ping消息间隔(毫秒),默认25秒。客户端向服务器发送一条心跳消息间隔
  pingInterval: 25000

3.创建配置类

@Configuration
public class SocketConfig {

    @Value("${socketio.host}")
    private String host;

    @Value("${socketio.port}")
    private Integer port;

    @Value("${socketio.bossCount}")
    private int bossCount;

    @Value("${socketio.workCount}")
    private int workCount;

    @Value("${socketio.allowCustomRequests}")
    private boolean allowCustomRequests;

    @Value("${socketio.upgradeTimeout}")
    private int upgradeTimeout;

    @Value("${socketio.pingTimeout}")
    private int pingTimeout;

    @Value("${socketio.pingInterval}")
    private int pingInterval;


    @Bean
    public SocketIOServer socketIOServer() {
        com.corundumstudio.socketio.SocketConfig socketConfig = new com.corundumstudio.socketio.SocketConfig();
        socketConfig.setReuseAddress(true);
        socketConfig.setTcpNoDelay(true);
        socketConfig.setSoLinger(0);

        com.corundumstudio.socketio.Configuration configuration = new com.corundumstudio.socketio.Configuration();
        configuration.setSocketConfig(socketConfig);
        // host在本地测试可以设置为localhost或者本机IP,在Linux服务器跑可换成服务器IP
        configuration.setHostname(host);
        configuration.setPort(port);
        // socket连接数大小(如只监听一个端口boss线程组为1即可)
        configuration.setBossThreads(bossCount);
        configuration.setWorkerThreads(workCount);
        configuration.setAllowCustomRequests(allowCustomRequests);
        // 协议升级超时时间(毫秒),默认10秒。HTTP握手升级为ws协议超时时间
        configuration.setUpgradeTimeout(upgradeTimeout);
        // Ping消息超时时间(毫秒),默认60秒,这个时间间隔内没有接收到心跳消息就会发送超时事件
        configuration.setPingTimeout(pingTimeout);
        // Ping消息间隔(毫秒),默认25秒。客户端向服务器发送一条心跳消息间隔
        configuration.setPingInterval(pingInterval);

        // 鉴权
        configuration.setAuthorizationListener(handshakeData -> {
            //获取socket链接发来的token参数
            String token = handshakeData.getSingleUrlParam("token");
            //如果验签通过就是true,否则false, false的话就不允许建立socket链接
            return true;
        });

        SocketIOServer socketIOServer = new SocketIOServer(configuration);

        return socketIOServer;
    }
}

4.服务端实现
4.1前端事件监听

@Component
public class EventListenner {
    @OnEvent("messageEvent")
    public void onEvent(SocketIOClient client, String message, AckRequest request) {

        System.out.println("收到推送消息:" + message);
        /*
        * 前端事件监听,自定义事件名称@OnEvent("messageEvent")
        * 逻辑处理
        * */
        request.sendAckData("推送已收到");//数据返回
    }
}

4.2创建通道连接缓存类 

public class ClientCache {
    /**
     * 本地缓存已连接的客户端
     */
    private static final Map<UUID, SocketIOClient> concurrentHashMap = new ConcurrentHashMap<>();
    /**
     * 存入本地缓存
     *
     * @param sessionId      页面sessionID
     * @param socketIOClient 页面对应的通道连接信息
     */
    public static void saveClient(UUID sessionId, SocketIOClient socketIOClient) {
        concurrentHashMap.put(sessionId, socketIOClient);
    }
    /**
     * 根据用户ID获取通道信息
     *
     * @param sessionId
     * @return
     */
    public static SocketIOClient getUserClient(UUID sessionId) {
        return concurrentHashMap.get(sessionId);
    }
    /**
     * 根据页面sessionID删除页面链接信息
     *
     * @param sessionId
     */
    public static void deleteSessionClient(UUID sessionId) {
        concurrentHashMap.remove(sessionId);
    }
    /**
     * 客户端集合实例获取
     */
    public static Map<UUID, SocketIOClient> getConcurrentHashMap(){
        return concurrentHashMap;
    }
}

4.3事件响应接口和实现类

public interface SocketIOService {

    /**
     * 启动服务
     **/
    void start();


    /**
     * 停止服务
     **/
    void stop();
}
@Slf4j
@Service
public class SocketIOServiceImpl implements SocketIOService {
    @Resource
    private SocketIOServer socketIOServer;
    @Resource
    private EventListenner eventListenner;

    /**
     * Spring IoC容器创建之后,在加载SocketIOServiceImpl Bean之后启动
     */
    @PostConstruct
    private void autoStartup() {
        start();
    }

    /**
     * Spring IoC容器在销毁SocketIOServiceImpl Bean之前关闭,避免重启项目服务端口占用问题
     */
    @PreDestroy
    private void autoStop() {
        stop();
    }

    @Override
    public void start() {
        // 监听客户端连接
        socketIOServer.addConnectListener(client -> {
            try {
                UUID sessionId = client.getSessionId();
                ClientCache.saveClient(sessionId, client);
                Map<UUID, SocketIOClient> concurrentHashMap = ClientCache.getConcurrentHashMap();
                log.info("连接成功,sessionId:{},当前有{}个连接", sessionId,concurrentHashMap.size());
            } catch (Exception e) {
                log.info("连接异常:"+e);
                client.sendEvent("connect",e.getMessage());
                throw new RuntimeException(e);
            }
        });
        // 监听客户端断开连接
        socketIOServer.addDisconnectListener(client -> {
            try {
                UUID sessionId = client.getSessionId();
                ClientCache.deleteSessionClient(sessionId);
                Map<UUID, SocketIOClient> concurrentHashMap = ClientCache.getConcurrentHashMap();
                log.info("关闭连接,sessionId:{},当前有{}个连接", sessionId,concurrentHashMap.size());
            } catch (Exception e) {
                log.info("断开异常:"+e);
                client.sendEvent("disconnect",e.getMessage());
                throw new RuntimeException(e);
            }
        });

        // 处理自定义的事件,与连接监听类似,event为事件名,PushMessage为参数实体类 添加监听类
        // 监听前端发送的事件消息推送事件
        socketIOServer.addListeners(eventListenner);
        log.info("消息推送服务启动完毕!");
        socketIOServer.start();
    }

    @Override
    public void stop() {

        if (socketIOServer != null) {
            socketIOServer.stop();
            socketIOServer = null;
        }
        log.info("消息推送服务已关闭!");
    }
}

4.4推送事件接口和实现类

public interface PushService {

    /**
     * 推送消息给客户
     *
     * @param message
     * @param sessionId
     */
    void pushUser(String message, UUID sessionId);
    /**
     * 推送消息给所有客户
     *
     * @param pushMessage
     */
    void pushChatMessage(String pushMessage);
}
@Service
public class PushServiceImpl implements PushService {

    /**
     * 推送给单个客户端
     */
    @Override
    public void pushUser(String message, UUID sessionId) {
        SocketIOClient socketIOClient = ClientCache.getUserClient(sessionId);
        if(socketIOClient!=null){
            socketIOClient.sendEvent("pushEvent", message);
        }

    }

    /**
     * 推送给所有客户端
     */
    @Override
    public void pushChatMessage(String pushMessage) {
        Map<UUID, SocketIOClient> concurrentHashMap = ClientCache.getConcurrentHashMap();
        concurrentHashMap.forEach((uuid, socketIOClient)->{
            socketIOClient.sendEvent("pushEvent",pushMessage);
        });
    }
}

5.客户端实现

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<script src="https://cdn.bootcss.com/socket.io/2.1.1/socket.io.js"></script>
<script type="text/javascript">

    var socket = io.connect('http://localhost:9091', {
        'reconnection delay' : 2000,
        'force new connection' : true,
    });

    socket.on('pushEvent', function(data) {
        // here is your handler on messages from server
        console.log(data)
        alert(data)
    });

    socket.on('connect', function(data) {
        console.log("连接失败异常:"+data);
    });

    socket.on('disconnect', function (data) {
        console.log("连接断开异常:"+data)
    });
    socket.emit('messageEvent', "cx",(data) => {
        console.log(data)
    });

</script>

标签:集成,springboot,socketio,void,private,sessionId,configuration,public
From: https://www.cnblogs.com/lshwl/p/18244363

相关文章

  • springboot3项目的搭建四.3(security登录认证配置)
    security的jwt验证:总体来说,我们加入依赖项,security就已经开始生效了,但是使用的默认的UserDetails和UserDetailsService,一、我们只要继承UserDetailsService,在数据库中查询用户和权限列表,封装成UserDetails的实现类,返回就可以实现,security验证的接管,最多在security配置类中,放行......
  • SpringBoot 多文件打包下载
    第一种@RestController@RequestMapping("/download")publicclassDownloadController{@GetMapping("/files")publicResponseEntity<InputStreamResource>downloadFiles()throwsIOException{//......
  • 【Jenkins+K8s】持续集成与交付 (二十):K8s集群通过Deployment方式部署安装Jenkins
    ......
  • HXJ8002F 3W带关断模式AB类音频功放集成电路芯片IC
    一般描述    HXJ8002F是一颗带关断模式的音频功放IC。在5V输入电压下工作时,负载(4Ω)上的平均功率为3W,且失真度不超过10%。而对于手提设备而言,当VDD作用于关断端时,HXJ8002F将会进入模戚,此时的功耗极低。    HXJ8002F的应用电路简单,只需极少数外围器件HXJ8002......
  • 网易面试:SpringBoot如何开启虚拟线程?
    虚拟线程(VirtualThread)也称协程或纤程,是一种轻量级的线程实现,与传统的线程以及操作系统级别的线程(也称为平台线程)相比,它的创建开销更小、资源利用率更高,是Java并发编程领域的一项重要创新。PS:虚拟线程正式发布于Java长期支持版(LongTermSuort,LTS)Java21(也就是JDK21)。......
  • SpringBoot面试准备 第一天
    什么是SpringBoot?简化Spring 应用程序开发的框架,通过自动配置、起步依赖和简化的配置方式,使开发人员能够更快速、方便地创建和配置Spring应用程序,提高开发效率和开发体验目标是使开发人员能够更加快速、方便地创建和配置Spring应用程序,同时尽可能地减少样板代码和繁琐......
  • 【CMake系列】10-cmake测试集成googletest与第三方库自动化构建
    cmake测试,使用ctest可能不能满足我们的需求,需要我们使用更为强大的第三方测试框架,如googletest,完成项目中的测试工作本篇文章将第三方测试框架googletest,引入,同时也可以作为关于第三方包自动化构建的很好示例,值得学习本专栏的实践代码全部放在github上,欢迎star!!!如......
  • 【接口自动化测试框架练习】springboot+react+mysql~极简版postman
    可以说是一个toyprogram,chatgpt完成了一部分工作,我也完成了一部分工作,我俩合作的,我占百分之80%,他百分之20%,哈哈没他不行,源码奉上。https://github.com/Jinwenxin/test-api-frontend1.功能简介:分成三部分,如左侧导航栏所示:测试用例管理:测试用例的增删改查以及运行测试套件管理......
  • LLM应用实战:当图谱问答(KBQA)集成大模型(三)
    1. 背景最近比较忙(也有点茫),本qiang~想切入多模态大模型领域,所以一直在潜心研读中...本次的更新内容主要是响应图谱问答集成LLM项目中反馈问题的优化总结,对KBQA集成LLM不熟悉的客官可以翻翻之前的文章《LLM应用实战:当KBQA集成LLM》、《LLM应用实战:当KBQA集成LLM(二)》。针对K......
  • 【S087】Springboot+Thymleaf在线答疑系统项目源码 java源代码
    运行截图:登录学生注册教师注册学生发起问题联系我们后台首页常见问题管理添加常见问题人工答疑学生管理个人信息修改密码项目组成:项目源码:源码获取⬇⬇⬇......