socket集成springboot项目

引入依赖:

java 复制代码
        <dependency>
            <groupId>com.corundumstudio.socketio</groupId>
            <artifactId>netty-socketio</artifactId>
            <version>1.7.7</version>
        </dependency>

配置类:

java 复制代码
package cn.netinnet.cbt.config;

import com.corundumstudio.socketio.SocketConfig;
import com.corundumstudio.socketio.SocketIOServer;
import com.corundumstudio.socketio.Transport;
import com.corundumstudio.socketio.annotation.SpringAnnotationScanner;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class SocketIOConfig {

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

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

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

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

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

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

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

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

    @Value("${socketio.maxFramePayloadLength:1048576}")
    private int maxFramePayloadLength;

    /**
     * 以下配置在上面的application.properties中已经注明
     * @return
     */
    @Bean
    public SocketIOServer socketIOServer() {
        SocketConfig socketConfig = new SocketConfig();
        socketConfig.setTcpNoDelay(true);
        socketConfig.setSoLinger(0);
        com.corundumstudio.socketio.Configuration config = new com.corundumstudio.socketio.Configuration();
        config.setSocketConfig(socketConfig);
        config.setHostname(host);
        config.setPort(port);
        config.setBossThreads(bossCount);
        config.setWorkerThreads(workCount);
        config.setAllowCustomRequests(allowCustomRequests);
        config.setUpgradeTimeout(upgradeTimeout);
        config.setPingTimeout(pingTimeout);
        config.setPingInterval(pingInterval);
        //设置最大每帧处理数据的长度,防止他人利用大数据来攻击服务器
        config.setMaxFramePayloadLength(maxFramePayloadLength);
        config.setTransports(Transport.POLLING, Transport.WEBSOCKET);
        return new SocketIOServer(config);
    }

    /**
     * 开启SocketIOServer注解支持
     */
    @Bean
    public SpringAnnotationScanner springAnnotationScanner(SocketIOServer socketServer) {
        return new SpringAnnotationScanner(socketServer);
    }
}

业务接口类:

java 复制代码
public interface WebSocketService{
    void receiveMessage(Message message, MultipartFile file);

}

实现类:

java 复制代码
@Service
public class WebSocketServiceImpl implements WebSocketService {
    @Autowired
    private SocketIOService socketIOService;

    @Autowired
    private NinCbtStuScoreService ninCbtStuScoreService;

    @Override
    public void receiveMessage(Message message, MultipartFile file) {
        StuScoreBO bo = new StuScoreBO();
        BeanUtils.copyProperties(message,bo);
        // 直播结束的时候
        if (BusinessConstant.LIVE_ROOM_END == message.getMessageType()) {
            if (null == file) {
                throw new BaseServiceException(BusinessConstant.SERVICE_ERRO_CODE, BusinessConstant.FILE_EPT);
            }
            String fileUrl = ninCbtStuScoreService.uploadStuFileForApp(bo, file);
            bo.setFileUrl(fileUrl);
        }
        ninCbtStuScoreService.initStuScore(bo,message);
        socketIOService.pushMessageToUser(message);
    }

}

socket逻辑接口:

java 复制代码
package cn.netinnet.cbt.service;


import cn.netinnet.cbt.bo.Message;
import cn.netinnet.cbt.constant.WsMsgTypeEnum;

public interface SocketIOService {

    //推送的事件
    String PUSH_EVENT = "push_event";

    String CONNECT_EVENT = "connect_event";

    // 启动服务
    void start() throws Exception;

    // 停止服务
    void stop();

    // 推送信息
    void pushMessageToUser(Message message);

}

实现类:

java 复制代码
package cn.netinnet.cbt.service.impl;

import cn.netinnet.cbt.bo.Message;
import cn.netinnet.cbt.service.SocketIOService;
import com.corundumstudio.socketio.SocketIOClient;
import com.corundumstudio.socketio.SocketIOServer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Service
public class SocketIOServiceImpl implements SocketIOService {

    // 用来存已连接的客户端
    private static Map<String, SocketIOClient> clientMap = new ConcurrentHashMap<>();

    @Autowired
    private SocketIOServer socketIOServer;


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

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

    @Override
    public void start() {
        // 监听客户端连接
        socketIOServer.addConnectListener(client -> {
        });

        // 监听客户端断开连接
        socketIOServer.addDisconnectListener(client -> {
            client.disconnect();
        });

        // 处理自定义的事件,与连接监听类似, 连接加入批次房间
        socketIOServer.addEventListener(CONNECT_EVENT, Message.class, (client, data, ackSender) -> {
            client.joinRoom("ec_cbt_room_" + data.getTeaClassSessionId() +"_"+ data.getUserId());
        });
        socketIOServer.addEventListener(PUSH_EVENT, Message.class, (client, data, ackSender) -> {
            socketIOServer.getRoomOperations("ec_cbt_room_" + data.getTeaClassSessionId() +"_"+ data.getUserId()).sendEvent(PUSH_EVENT, "现在是这个ip连着" + data);
        });
        socketIOServer.start();
    }

    @Override
    public void stop() {
        if (socketIOServer != null) {
            socketIOServer.stop();
            socketIOServer = null;
        }
    }

    /**
     * 推送信息
     * @param message
     */
    @Override
    public void pushMessageToUser(Message message) {
        socketIOServer.getRoomOperations("ec_cbt_room_" + message.getTeaClassSessionId() +"_"+ message.getUserId()).sendEvent(PUSH_EVENT, message);
    }


    /**
     * 此方法为获取client连接中的参数,可根据需求更改
     * @param client
     * @return
     */
    private String getParamsByClient(SocketIOClient client) {
        // 从请求的连接中拿出参数(这里的loginUserNum必须是唯一标识)
        Map<String, List<String>> params = client.getHandshakeData().getUrlParams();
            List<String> list = params.get("batchId");
        if (list != null && list.size() > 0) {
            return list.get(0);
        }
        return null;
    }
}

前端仿客户端:

java 复制代码
<html>
<head>
    <meta charset="utf-8"/>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.1.0/socket.io.js"></script>
<!--    <script src="socket.io.js"></script>-->
    <script>

        var socket = null;
        var i = 0;
        window.onload = function(){
            initSocket();
        }
        function getCookie(c_name)
        {
            if (document.cookie.length>0)
            {
                c_start=document.cookie.indexOf(c_name + "=")
                if (c_start!=-1)
                {
                    c_start=c_start + c_name.length+1
                    c_end=document.cookie.indexOf(";",c_start)
                    if (c_end==-1) c_end=document.cookie.length
                    return unescape(document.cookie.substring(c_start,c_end))
                }
            }
            return ""
        }
        function initSocket(){
            socket = io.connect('http://172.30.6.68:9098', { "transports":["websocket"]} ); //正式发布环境
            // socket = io('http://localhost:8974/test'); //正式发布环境
            socket.on('connect', function () {
				socket.emit("connect_event", {"teaClassSessionId":1111,"userId":880785304192290816});
                console.log('socket连接成功');

            });

            socket.on('disconnect', function () {
                console.log('socket断开连接');
            });


            //==============以下使用命名空间test========================

            //监听广播消息
            socket.on('testNamespace', function (data) {
                console.log("接收到消息:" + data);
            });

            //监听点对点消息
            socket.on('bbbb', function (data) {
                //....收到消息后具体操作
                //  console.log(data);
                console.log(data);
            });

            socket.on('push_event', function (data) {
                //....收到消息后具体操作
                //  console.log(data);
                console.log(data);
            });

            //监听后端无限推送的点对点消息
            socket.on('testPush', function (data) {
                console.log("接收到消息的次数:" + ++i);
            });

            //监听加入房间的反馈
            socket.on('testJoinRoom', function (data) {
                console.log("接收到消息:" + data);
            });

            //监听房间消息
            socket.on('testRoom', function (data) {
                console.log("接收到消息:" + data);
            });
            //监听广播消息
            socket.on('testBroadcast', function (data) {
                console.log("接收到消息:" + data);
            });

        }

        //发送点对点消息
        function send(){
            socket.emit('push_event', {"teaClassId":1111,"userId":3333,"content":"直播结束"});
        }
        //触发无限推送
        function send2(){
            socket.emit('testPush', "begin");
        }
        //发送加入房间消息
        function send3(){
            socket.emit('joinRoom', "room1");
        }
        //发送房间消息
        function send4(){
            socket.emit('testRoom', "testRoomData");
        }
        //发送广播消息
        function send5(){
            socket.emit('testBroadcast', "testBroadCastData");
        }


    </script>

    <input type="button" value="发送点对点消息" onclick="send();">
    <br/><br/>
    <input type="button" value="开启无限推送测试" onclick="send2();">
    <br/><br/>
    <input type="button" value="测试加入房间" onclick="send3();">
    <br/><br/>
    <input type="button" value="测试房间内发消息" onclick="send4();">
    <br/><br/>
    <input type="button" value="测试发送广播消息" onclick="send5();">
    <br/><br/>

</head>
</html>
相关推荐
陈平安Java and C5 小时前
MyBatisPlus
java
秋野酱5 小时前
如何在 Spring Boot 中实现自定义属性
java·数据库·spring boot
安的列斯凯奇6 小时前
SpringBoot篇 单元测试 理论篇
spring boot·后端·单元测试
Bunny02126 小时前
SpringMVC笔记
java·redis·笔记
架构文摘JGWZ6 小时前
FastJson很快,有什么用?
后端·学习
BinaryBardC6 小时前
Swift语言的网络编程
开发语言·后端·golang
feng_blog66886 小时前
【docker-1】快速入门docker
java·docker·eureka
邓熙榆6 小时前
Haskell语言的正则表达式
开发语言·后端·golang
枫叶落雨2228 小时前
04JavaWeb——Maven-SpringBootWeb入门
java·maven
m0_748232398 小时前
SpringMVC新版本踩坑[已解决]
java