socketio.emit 不起作用 netty socketio

pac*_*man 2 java socket.io spring-boot netty-socketio

我正在使用 java 的 socketio 和 netty,而且我对它们都是新手。

\n

我的客户端代码如下所示。

\n
<!DOCTYPE html>\n<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">\n<head>\n    <title >webSocket test</title>\n    <script src="http://code.jquery.com/jquery-1.12.4.min.js"></script>\n    <script src="https://cdn.socket.io/3.1.3/socket.io.min.js" integrity="sha384-cPwlPLvBTa3sKAgddT6krw0cJat7egBga3DJepJyrLl4Q9/5WLra3rrnMcyTyOnh" crossorigin="anonymous"></script>\n    < !-- New Bootstrap core CSS file-->\n    <!-- Optional Bootstrap theme file (generally not necessary to import) -->\n    <!- -jQuery file. Be sure to introduce before bootstrap.min.js -->\n\n    <!-- The latest Bootstrap core JavaScript file-->\n    <script type=" text/javascript">\n        $(function(){\n            /**\n             * The socket.emit("event name", "parameter data") method of the\n             front-end js is used when triggering the back-end custom message event, * front-end js The socket.on("event name", anonymous function (data sent by the server to the client)) for monitoring server-side events\n             **/\n\n            //io({path: 'ws://localhost:9099/', transports: ['websocket'] ,upgrade: false});\n\n            var socket = io.connect("ws://localhost:9099",{transports: ['websocket'] ,upgrade: false});\n            var firstconnect = true;\n            if(firstconnect) {\n                console.log("First connection initialization");\n                //Monitor server connection event\n                socket.on('connect',function(){\n                    socket.emit('messageEvent', 'Hello server');\n                    console.log("First connection success");\n                    $("#tou").html("Connect to the server successfully!");\n                     });\n\n                //Monitor server shutdown service event\n\n                socket.on('disconnect', function(){\n                    $("#tou").html("Disconnected from the server!");\n                    });\n                //Monitor server Send message event\n                socket.on('responseEvent', function(data) {\n                    console.log('data');\n                    $("#msg").html($("#msg").html() + "<br/>" + data);\n                } );\n                firstconnect = false;\n            } else {\n                console.log("why?");\n                socket.socket.reconnect();\n            }\n\n            $('#send').bind('click', function() {\n                send();\n            });\n\n            function send(){\n                if (socket != null) {\n                    var message = document.getElementById('message').value;\n                    var title = "message";\n                    var obj = {message:message,title:title};\n                    var str = JSON.stringify(obj);\n                    socket.emit("messageEvent",str);\n                    console.log("message event" , str);\n\n                } else {\n                    alert('Send');\n                }\n            }\n        });\n    </script>\n\n</head>\n<body>\n<div class="page-header" id="tou">\n    webSocket Demo\n</div>\n<div class="well" id="msg">\n</div>\n<div class="col-lg">\n    <div class="input-group">\n        <input type="text" class="form-control" placeholder="send Message..." id="message">\n        <span class="input-group-btn">\n        <button class="btn btn-default" type="button" id="send" >send</button>\n      </span>\n    </div><!-- /input-group -->\n</div><!-- /.col-lg-6 -->\n</div><!-- /.row --><br><br>\n\n</body>\n</html>\n\n
Run Code Online (Sandbox Code Playgroud)\n

事件处理程序如下所示。

\n
@Component\npublic class MessageEventHandler {\n\n    private static final Logger logger  = LoggerFactory.getLogger(MessageEventHandler.class);\n\n    public static ConcurrentMap<String, SocketIOClient> socketIOClientMap = new ConcurrentHashMap<>();\n\n\n    @Autowired\n    private RedissonClient redisson;\n\n    @Resource\n    private SocketIOServer socketIOServer;\n\n    @OnConnect\n    public void  onConnect(SocketIOClient client){\n        Map<String,Object> clientMap = new HashMap<>(16);\n\n        client.sendEvent("responseEvent", client.getSessionId().toString()+": "+ "hello");\n\n        if(client!=null){\n            String room = client.getHandshakeData().getSingleUrlParam("room");\n            String nameSpace = client.getNamespace().getName();\n            logger.info("namespace {} ",nameSpace);\n\n            String sessionId = client.getSessionId().toString();\n            logger.info("namespace, room={}, sessionId={},namespace={}",room,sessionId,nameSpace);\n            if(StringUtils.isEmpty(room)){\n                //client.joinRoom(room);\n                clientMap.put("rooms",room);\n            }\n            clientMap.put("createTime", LocalDateTime.now().toString());\n            redisson.getBucket("room"+sessionId).trySet(clientMap);\n\n        }\n\n        return;\n    }\n\n    /**\n     * Triggered when the client closes the connection\n     *\n     * @param client\n     */\n    @OnDisconnect\n    public void onDisconnect(SocketIOClient client) {\n        logger.info("client:" + client.getSessionId() + "disconnected");\n    }\n\n    /**\n     * Client events\n     *\n     * @param client  \xe3\x80\x80\n     * @param request\n     * @param msg    \xe3\x80\x80\n     */\n    @OnEvent(value = "messageEvent")\n    public void onMessageEvent(SocketIOClient client, AckRequest request, String msg) {\n\n        System.out.println("haha");\n        logger.info("message \xef\xbc\x9a" + msg);\n\n        //Post the message back\n        JSONObject jsonObject = JSON.parseObject(msg);\n        String message = jsonObject.getString("message");\n        Collection<SocketIOClient> clients = socketIOServer.getBroadcastOperations().getClients();\n        for (SocketIOClient clientByRoom : clients) {\n            clientByRoom.sendEvent("responseEvent", client.getSessionId().toString()+":   "+message);\n        }\n    }\n\n}\n
Run Code Online (Sandbox Code Playgroud)\n

服务器启动代码如下所示。

\n
\n@Component\n@Order(1)\npublic class SocketServerRunner implements CommandLineRunner {\n\n    private static Logger logger = LoggerFactory.getLogger(SocketServerRunner.class);\n\n    @Resource\n    private SocketIOServer socketIOServer;\n\n    @Resource\n    private PubSubStore pubSubStore;\n\n    @Autowired\n    private RedissonClient redisson;\n\n    @Override\n    public void run(String... args) throws Exception {\n        logger.info("socketIOServer ");\n        socketIOServer.start();\n\n        pubSubStore.subscribe(PubSubType.DISPATCH, data -> {\n            Collection<SocketIOClient> clients = null;\n            String room = data.getRoom();\n            String namespace = data.getNamespace();\n            Packet packet = data.getPacket();\n            String jsonData = packet.getData();\n            if(!StringUtils.isEmpty(namespace)){\n                SocketIONamespace socketIONamespace = socketIOServer.getNamespace(namespace);\n                if(StringUtils.isEmpty(room)){\n                    clients = socketIONamespace.getRoomOperations(room).getClients();\n                }\n            }else{\n                clients = socketIOServer.getBroadcastOperations().getClients();\n            }\n\n            if(!CollectionUtils.isEmpty(clients)){\n                for (SocketIOClient client : clients) {\n                    client.sendEvent("messageEvent",jsonData);\n                }\n            }\n        }, DispatchMessage.class);\n       // addNameSpace(socketIOServer);\n    }\n\n
Run Code Online (Sandbox Code Playgroud)\n

我在带注释的方法上进行了连接注册OnConnect,但该方法似乎运行了两次,因为在套接字连接时我获得了日志两次。我不知道为什么会这样。

\n

但更糟糕的是,用客户端 JavaScript 编写的 emit 方法不起作用。没有错误。执行emit下面的日志。但是OnEventjava EventHandler中的注释方法似乎没有检测到它。

\n

有人可以帮助我理解这一点吗?

\n

pac*_*man 6

显然问题出在库上。新版本的 socketio 客户端库与 java 的 netty 依赖项存在一些兼容性问题,这导致了奇怪的问题。

我对 netty socketio 的依赖如下所示,这显然是回答这个问题时最新的。

        <dependency>
            <groupId>com.corundumstudio.socketio</groupId>
            <artifactId>netty-socketio</artifactId>
            <version>1.7.19</version>
        </dependency>
Run Code Online (Sandbox Code Playgroud)

为了使客户端库顺利工作,我必须将库从 3.XX 降级到 2.XX 。

就我而言,来自

<script src="https://cdn.socket.io/3.1.3/socket.io.min.js" integrity="sha384-cPwlPLvBTa3sKAgddT6krw0cJat7egBga3DJepJyrLl4Q9/5WLra3rrnMcyTyOnh" crossorigin="anonymous"></script>
Run Code Online (Sandbox Code Playgroud)

<script src="https://cdn.bootcss.com/socket.io/2.1.1/socket.io.js"></script>
Run Code Online (Sandbox Code Playgroud)