java socketio 入门教程(自制聊天系统)

mac2025-06-07  55

java socketio 入门Demo

WebSocket :一种通信协议 ,其作用建立一个连接通道,使数据交互从传统的请求响应的方式 改为了实时的双向推送 ,解决了 http 协议的部分不足

这里就直接整合了spring boot,spring boot 太香了

聊天demo代码(服务器版)

依赖(没贴spring boot的) <dependency> <groupId>com.corundumstudio.socketio</groupId> <artifactId>netty-socketio</artifactId> <version>1.7.11</version> </dependency> 设置全局的配置对象 @Configuration public class SocketConfig { private int PORT = 8081; private String HOST = "localhost"; @Bean public SocketIOServer socketIOServer() { com.corundumstudio.socketio.Configuration config = new com.corundumstudio.socketio.Configuration(); //不设置主机、默认绑定0.0.0.0 or ::0 // config.setHostname(WSS_HOST); config.setPort(PORT); //这里还可以认证很多设置 比如仓库什么的 //身份验证 config.setAuthorizationListener(handshakeData -> { //这里没有启用任何认证 直接返回为 true,可以在这里写用户认证的逻辑 //http://localhost:8081?username=test&password=test // //例如果使用上面的链接进行connect,可以使用如下代码获取用户密码信息 // //String username = data.getSingleUrlParam("username"); // //String password = data.getSingleUrlParam("password"); return true; }); final SocketIOServer server = new SocketIOServer(config); return server; } @Bean public SpringAnnotationScanner springAnnotationScanner(SocketIOServer socketServer) { return new SpringAnnotationScanner(socketServer); } } 编写消息处理者 @Component public class MessageHandler { private static final Logger log = LoggerFactory.getLogger(MessageHandler.class); //会话集合,用来存储所有的客户端信息 private static final ConcurrentSkipListMap<String, ClientInfo> webSocketMap = new ConcurrentSkipListMap<>(); //静态变量,用来记录当前在线连接数。(原子类、线程安全) private static AtomicInteger onlineCount = new AtomicInteger(0); //服务器全局对象 发送信息 就靠它了 private final SocketIOServer server; @Autowired public MessageHandler(SocketIOServer server) { this.server = server; } /** * connect事件处理,当客户端发起连接时将调用,每次建立连接都会调用一次该方法 * * @param client */ @OnConnect public void onConnect(SocketIOClient client) { // clientid 来自请求地址中 String clientId = client.getHandshakeData().getSingleUrlParam("clientid"); log.info("web socket连接:" + clientId); UUID session = client.getSessionId(); ClientInfo si = webSocketMap.get(clientId); // 如果没有连接信息、则新建会话信息 if (si == null) { si = new ClientInfo(); si.setOnline(true); //在线数加1 log.info("socket 建立新连接、sessionId:" + session + "、clientId:" + clientId + "、当前连接数:" + onlineCount.incrementAndGet()); } // 更新客户端连接信息 si.setLeastSignificantBits(session.getLeastSignificantBits()); si.setMostSignificantBits(session.getMostSignificantBits()); si.setLastConnectedTime(new Date()); //将会话信息更新保存至集合中 webSocketMap.put(clientId, si); } public void sendMessage(Object Message) { // 这个方法 会向所有的客户端 发送信息。 事件名为 message_event // 只有客户端有监听这个事件 就能接收到信息 for (String clientId : webSocketMap.keySet()) { ClientInfo clientInfo = webSocketMap.get(clientId); System.out.printf("开始往客户端%s发送数据", clientId); UUID session = new UUID(clientInfo.getMostSignificantBits(), clientInfo.getLeastSignificantBits()); server.getClient(session).sendEvent("message_event", Message); } } /** * 断开连接 * * @param client */ @OnDisconnect public void onDisconnect(SocketIOClient client) { String clientId = client.getHandshakeData().getSingleUrlParam("clientid"); webSocketMap.remove(clientId); //在线数减1 log.info("socket 断开连接、sessionId:" + client.getSessionId() + "、clientId:" + clientId + "、当前连接数:" + onlineCount.decrementAndGet()); } /** * 消息接收入口,当接收到消息后,查找发送目标客户端,并且向该客户端发送消息,且给自己发送消息 * * @param client * @param request * @param data */ // onEvnt 对某个事件进行监听 当客户端有触发这个事件时候 调用。这里是一个聊天的逻辑处理 @OnEvent(value = "message_event") public void onEvent(SocketIOClient client, AckRequest request, MessageInfo data) { // MessageInfo 该对象 由客户端发送事件时候提供 String targetClientId = data.getTargetClientId(); ClientInfo clientInfo = webSocketMap.get(targetClientId); //如果目标在线 那么发送消息,如果不在线 就不进行处理 if (clientInfo != null && clientInfo.isOnline()) { UUID target = new UUID(clientInfo.getMostSignificantBits(), clientInfo.getLeastSignificantBits()); log.info("目标会话UUID:" + target); MessageInfo sendData = new MessageInfo(); sendData.setSourceClientId(data.getSourceClientId()); sendData.setTargetClientId(data.getTargetClientId()); sendData.setMsg(data.getMsg()); // 向当前会话发送信息 client.sendEvent("message_event", sendData); // 向目标会话发送信息 server.getClient(target).sendEvent("message_event", sendData); } } /** * socket会话信息 * 下面是自定义的一些消息对象 */ @Data public class ClientInfo { private String clientId; private boolean isOnline; private long mostSignificantBits; private long leastSignificantBits; private Date lastConnectedTime; } /** * 消息对象 */ public static class MessageInfo { //源客户端id private String sourceClientId; //目标客户端id private String targetClientId; //消息内容 private String msg; // get/set方法 .... public void setSourceClientId(String sourceClientId) { this.sourceClientId = sourceClientId; } public void setTargetClientId(String targetClientId) { this.targetClientId = targetClientId; } public void setMsg(String msg) { this.msg = msg; } public String getSourceClientId() { return sourceClientId; } public String getTargetClientId() { return targetClientId; } public String getMsg() { return msg; } } }

客户端代码

客户端1

<!DOCTYPE html> <html> <head lang="zh"> <meta charset="utf-8"/> <meta http-equiv="Content-Type" content="text/html; charset=gb2312"> <title>Demo Chat</title> <link href="https://cdn.bootcss.com/bootstrap/4.0.0-alpha.6/css/bootstrap.css" rel="stylesheet"> <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/1.7.3/socket.io.js"></script> <!--moment js下载地址:http://momentjs.com/ --> <script src="moment.js"></script> <script src="http://code.jquery.com/jquery-1.10.1.min.js"></script> <style> body {padding: 20px;} #console {height: 400px;overflow: auto;} .username-msg {color: orange;} .connect-msg {color: green;}.disconnect-msg {color: red;}.send-msg {color: #888} </style> <script> var clientId = 'user1',targetId = 'user2'; var socket = io.connect('http://localhost:8081?clientid=' + clientId); socket.on('connect', function () { showMsg('<span class="connect-msg">成功连接到服务器!</span>'); }); socket.on('message_event', function (data) { showMsg('<br /><span class="username-msg">' + new Date().getHours()+' '+new Date().getMinutes()+' '+new Date().getSeconds()+ '</span> ' + data); }); socket.on('disconnect', function () { showMsg('<span class="disconnect-msg">服务已断开!</span>'); }); function sendDisconnect() { socket.disconnect(); } function sendMessage() { var message = $('#msg').val(); $('#msg').val(''); var jsonObject = { sourceClientId: clientId, targetClientId: targetId, msg: message }; socket.emit('message_event', jsonObject); } function showMsg(message) { // alert(message) // var currentTime = "<span class='time'>" + moment().startOf('hour').fromNow() + "</span>"; // var element = $("<div>" + currentTime + "" + message + "</div>"); $('#console').append(message); } $(document).keydown(function (e) { if (e.keyCode == 13) { $('#send').click(); } }); </script> </head> <body> <h1>Netty-socket.io Demo</h1><br/> <div id="console" class="well"></div> <form class="well form-inline" onsubmit="return false;"> <input id="msg" class="input-xlarge" type="text" placeholder="Type something..."/>&nbsp;&nbsp; <button type="button" onClick="sendMessage()" class="btn" id="send">Send</button>&nbsp;&nbsp; <button type="button" onClick="sendDisconnect()" class="btn">Disconnect</button> </form> </body> </html>

客户端2

<!DOCTYPE html> <html> <head lang="zh"> <meta charset="utf-8"/> <meta http-equiv="Content-Type" content="text/html; charset=gb2312"> <title>Demo Chat</title> <link href="https://cdn.bootcss.com/bootstrap/4.0.0-alpha.6/css/bootstrap.css" rel="stylesheet"> <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/1.7.3/socket.io.js"></script> <!--moment js下载地址:http://momentjs.com/ --> <script src="moment.js"></script> <script src="http://code.jquery.com/jquery-1.10.1.min.js"></script> <style> body {padding: 20px;} #console {height: 400px;overflow: auto;} .username-msg {color: orange;} .connect-msg {color: green;}.disconnect-msg {color: red;}.send-msg {color: #888} </style> <script> var clientId = 'user2',targetId = 'user1'; var socket = io.connect('http://localhost:8081?clientid=' + clientId); socket.on('connect', function () { showMsg('<span class="connect-msg">成功连接到服务器!</span>'); }); socket.on('message_event', function (data) { showMsg('<br /><span class="username-msg">' + new Date().getHours()+' '+new Date().getMinutes()+' '+new Date().getSeconds()+ '</span> ' + data); }); socket.on('disconnect', function () { showMsg('<span class="disconnect-msg">服务已断开!</span>'); }); function sendDisconnect() { socket.disconnect(); } function sendMessage() { var message = $('#msg').val(); $('#msg').val(''); var jsonObject = { sourceClientId: clientId, targetClientId: targetId, msg: message }; socket.emit('message_event', jsonObject); } function showMsg(message) { // alert(message) // var currentTime = "<span class='time'>" + moment().startOf('hour').fromNow() + "</span>"; // var element = $("<div>" + currentTime + "" + message + "</div>"); $('#console').append(message); } $(document).keydown(function (e) { if (e.keyCode == 13) { $('#send').click(); } }); </script> </head> <body> <h1>Netty-socket.io Demo</h1><br/> <div id="console" class="well"></div> <form class="well form-inline" onsubmit="return false;"> <input id="msg" class="input-xlarge" type="text" placeholder="Type something..."/>&nbsp;&nbsp; <button type="button" onClick="sendMessage()" class="btn" id="send">Send</button>&nbsp;&nbsp; <button type="button" onClick="sendDisconnect()" class="btn">Disconnect</button> </form> </body> </html>

同时启动这个两个就能进行聊天了

最新回复(0)