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
,但该方法似乎运行了两次,因为在套接字连接时我获得了日志两次。我不知道为什么会这样。
但更糟糕的是,用客户端 JavaScript 编写的 emit 方法不起作用。没有错误。执行emit下面的日志。但是OnEvent
java EventHandler中的注释方法似乎没有检测到它。
有人可以帮助我理解这一点吗?
\n显然问题出在库上。新版本的 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)
归档时间: |
|
查看次数: |
2042 次 |
最近记录: |