spring boot Java实现网页一对一一对多实时聊天 webSocket

    xiaoxiao2022-07-13  194

    Java实现网页一对一 一对多实时聊天websocket

    后台代码 最重要的类

    package com.socket.websocket.chat; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import org.springframework.stereotype.Component; import java.io.File; import java.io.IOException; import java.util.Hashtable; import java.util.Map; import javax.websocket.OnClose; import javax.websocket.OnError; import javax.websocket.OnMessage; import javax.websocket.OnOpen; import javax.websocket.Session; import javax.websocket.server.PathParam; import javax.websocket.server.ServerEndpoint; /** * websocket * @author CHHUANG */ @ServerEndpoint("/webSocket/{senderId}") // 该注解用来指定一个URI,客户端可以通过这个URI来连接到WebSocket。类似Servlet的注解mapping。无需在web.xml中配置。 @Component public class WebChat { // 用来存放每个客户端对应的ChatAnnotation对象,实现服务端与单一客户端通信的话,使用Map来存放,其中Key可以为用户标识,hashtable比hashmap线程安全 private static Map<String, WebChat> webSocketMap = new Hashtable(); // 与某个客户端的连接会话,需要通过它来给客户端发送数据 private Session session; /** * 连接建立成功调用的方法 * @param session 可选的参数。session为与某个客户端的连接会话,需要通过它来给客户端发送数据 */ @OnOpen public void onOpen(@PathParam(value="senderId") String senderId, Session session) { this.session = session; webSocketMap.put(senderId,this);//加入map中 System.out.println(senderId+"连接加入!当前在线人数为"+getOnlineCount()); } /** * 连接关闭调用的方法 */ @OnClose public void onClose(@PathParam(value="senderId") String userId) { webSocketMap.remove(userId); System.out.println(userId+"关闭连接!当前在线人数为" + getOnlineCount()); } /** * 收到客户端消息后调用的方法 * @param message 客户端发送过来的消息 * @param session 可选的参数 */ @OnMessage public void onMessage(@PathParam(value="senderId") String senderId, String message, Session session) { // 群发消息 try { //将前端发送的 JSON 字符串转换为 JSON 对象 JSONObject jsonMessge = JSON.parseObject(message); //获取接收者ID列表 JSONArray list = jsonMessge.getJSONArray("userList"); //获取发送者的聊天对象 WebChat userMap = webSocketMap.get(senderId); //获取发送的消息 String mess=jsonMessge.getString("mess"); //为自己发送一条消息 userMap.sendMessage(mess); //遍历消息接受者列表 for (Object receiverId : list) { //获取消息接受者 WebChat receiver = webSocketMap.get(receiverId); //调用session的发送消息方法 将消息发送到客户端 receiver.sendMessage(mess); } } catch (Exception e) { e.printStackTrace(); } } /** * 发生错误时调用 * @param session * @param error */ @OnError public void onError(@PathParam(value="userId") String userId, Session session, Throwable error) { System.out.println(userId+"发生错误"); error.printStackTrace(); } /** * 发送消息 * 这个方法与上面几个方法不一样。没有用注解,是根据自己需要添加的方法。 * @param message * @throws IOException */ public void sendMessage(String message) throws IOException { this.session.getBasicRemote().sendText(message); } /** * 发送文件 * @throws IOException */ public void sendFile(File file)throws IOException{ this.session.getAsyncRemote().sendObject(file); } public static synchronized int getOnlineCount() { return webSocketMap.size(); } }

    配置类

    package com.socket.websocket.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.socket.server.standard.ServerEndpointExporter; @Configuration public class WebSocketConfig { @Bean public ServerEndpointExporter serverEndpointExporter() { System.out.println(">>>>>>>>>>>>>>>>>启用 WebSocket"); return new ServerEndpointExporter(); } }

    pom.xml

    <!--websocket连接需要使用到的包--> <dependency> <groupId>javax.websocket</groupId> <artifactId>javax.websocket-api</artifactId> <version>1.1</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency> <dependency> <groupId>javax</groupId> <artifactId>javaee-api</artifactId> <version>7.0</version> <scope>provided</scope> </dependency> <!-- webSocket 结束--> <!-- fastjson JSON--> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.31</version> </dependency>

    前端代码

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <style type="text/css"> input#chat { width: 410px } #console-container { width: 400px; } #console { border: 1px solid #CCCCCC; border-right-color: #999999; border-bottom-color: #999999; height: 170px; overflow-y: scroll; padding: 5px; width: 100%; } #console p { padding: 0; margin: 0; } </style> <body> <div> <p> <input type="text" placeholder="type and press enter to chat" id="chat" /> </p> <div id="console-container"> <div id="console"></div> </div> <script type="text/javascript"> var Console = {}; var mess={}; var userList=[]; var senderId=prompt("请输入你的账号"); Console.log = (function(message) { var console = document.getElementById('console'); var p = document.createElement('p'); p.style.wordWrap = 'break-word'; p.innerHTML = message; console.appendChild(p); while (console.childNodes.length > 25) { console.removeChild(console.firstChild); } console.scrollTop = console.scrollHeight; }); var Chat = {}; Chat.socket = null; Chat.connect = (function(host) { if ('WebSocket' in window) { Chat.socket = new WebSocket(host); } else if ('MozWebSocket' in window) { Chat.socket = new MozWebSocket(host); } else { Console.log('错误'); return; } Chat.socket.onopen = function() { Console.log('打开连接'); document.getElementById('chat').onkeydown = function(event) { if (event.keyCode == 13) { Chat.sendMessage(); } }; }; Chat.socket.onclose = function() { document.getElementById('chat').onkeydown = null; Console.log('关闭.'); }; Chat.socket.onmessage = function(message) { Console.log(message.data); }; }); Chat.initialize = function() { Chat.connect('ws://127.0.0.1:8080/webSocket/'+senderId); }; Chat.sendMessage = (function() { var message = document.getElementById('chat').value; var receiverIds=prompt("请输入接收者账号用逗号分隔"); userList=receiverIds.split(","); mess.userList=userList; mess.mess=message; var strmee=JSON.stringify(mess) if (message != '') { //发送 Chat.socket.send(strmee); //清空输入框 document.getElementById('chat').value=''; } }); Chat.initialize(); </script> </div> </body> </html>

    第一次发帖…复制别人的稍微做了修改 可以把html打开多个页面进行测试 用的是spring boot 有条件的可以在 我的主页去找源码 没条件的去这里 https://pan.baidu.com/s/1DcnrdiSlh1CQAe9SUg5rcg 取件码:hhva

    最新回复(0)