SpringBoot使用websocket实现简单聊天室
1.实现代码
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId></dependency><dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId></dependency><dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId></dependency>
@Configurationpublic class WebsocketConfig { @Bean public ServerEndpointExporter serverEndpointExporter() { return new ServerEndpointExporter(); }}
@Slf4j@Component@ServerEndpoint(value = "/ws/chat")public class ChatSocketServer { public static final AtomicInteger onlineCount = new AtomicInteger(0); public static Map<String, Session> clients = new ConcurrentHashMap<>(); /** * 连接建立成功调用的方法 */ @OnOpen public void onOpen(Session session) { String username=session.getRequestParameterMap().get("username").get(0); log.info("有新的客户端上线 sessionid={} username={}", session.getId(),username); clients.put(username,session); int cnt = onlineCount.incrementAndGet(); // 在线数加1 log.info("有连接加入,当前在线人数为:{}", cnt); } /** * 连接关闭调用的方法 */ @OnClose public void onClose(Session session) { clients.remove(session); int cnt = onlineCount.decrementAndGet(); log.info("在线人数为:{}", cnt); } /** * 出现错误 */ @OnError public void onError(Session session, Throwable error) { log.error("发生错误:{},Session ID: {}",error.getMessage(),session.getId()); error.printStackTrace(); } /** * 收到客户端消息后调用的方法 * @param message 客户端发送过来的消息 */ @OnMessage public void onMessage(String message, Session session) { log.info("消息:{}",message); //SendMessage(session, "收到消息,消息内容:" message); } /** * 发送消息,username为空就群发 */ public static void SendMessage(Message message) throws IOException { //username为空就群发 if(StringUtils.isBlank(message.getTo())){ for (Map.Entry<String,Session> entry: clients.entrySet()) { Session session=entry.getValue(); if(session.isOpen()){ session.getBasicRemote().sendText(JSON.toJSONString(message)); } } }else{ for (Map.Entry<String,Session> entry: clients.entrySet()) { if(entry.getKey().equals(message.getTo())){ Session session=entry.getValue(); if(session!=null && session.isOpen()){ session.getBasicRemote().sendText(JSON.toJSONString(message)); }else{ log.warn("没有找到你指定用户:{}",message.getTo()); } break; } } } }}
@Controllerpublic class ChatController {@GetMapping("/")public String index(){return "chat";}@GetMapping("/chat/send")@ResponseBodypublic AjaxResult send(String from,String to,String message) throws IOException {ChatSocketServer.SendMessage(new Message(from,to,message,new Date()));return AjaxResult.success();}//在线用户列表@GetMapping("/getOnlineUser")@ResponseBodypublic AjaxResult getOnlineUser() {return AjaxResult.success(ChatSocketServer.clients.keySet());}}
@Data@Builder@NoArgsConstructor@AllArgsConstructorpublic class Message { private String from; private String to; private String message; private Date time;}
<!DOCTYPE html><html lang="zh" xmlns:th="http://www.thymeleaf.org"><head> <meta charset="UTF-8"> <title>网页聊天室</title> <style type="text/css"> .chatdiv{width: 800px;height: 300px;padding: 10px;margin: 10px;border: #444 solid 1px;} .myshuo{text-align: right;border-bottom: #ccc solid 1px;padding: 5px 0;color: green;width: 100%} .othershuo{text-align: left;border-bottom: #ccc solid 1px;padding: 5px 0;color: dodgerblue;width: 100%} .xitongshuo{text-align: center;border-bottom: #ccc solid 1px;padding: 5px 0;color: red;font-weight: bold;width: 100%} </style></head><body><div id="loginpage" style="display: block"> <h3>用户登陆</h3> 输入用户名:<input type="text" id="username"><input type="button" onclick="login()" value="登陆"></div><div id="chatpage" style="display: none"> <div class="chatdiv" id="chatdiv"></div> <div> <select id="to" multiple="multiple" size="5"> </select> <input type="button" onclick="getOnlineUser()" value="刷新当前在线用户"> <input type="text" id="text"><input type="button" onclick="sendMessage()" value="发送"> </div></div><script src="https://apps.bdimg.com/libs/jquery/1.11.3/jquery.min.js"></script><script type="text/javascript"> var socket; var myusername=""; function getOnlineUser(){ $.get("/getOnlineUser",{},function(result){ $("#to").empty(); $("#to").append($("<option>").val("").text("全部")); for(var i=0;i<result.data.length;i ){ $("#to").append($("<option>").val(result.data[i]).text(result.data[i])); } },'json'); } function sendMessage(){ var text=$("#text").val(); if(text==''){ alert('消息内容不能为空'); return; } var to=$("#to").val()[0]; if(to!=''){ $("#chatdiv").append("<div class='myshuo'>我说:" text "</div>"); } $.get("/chat/send",{from:myusername,to:to,message:text},function(result){ console.info(result); $("#text").val(""); },'json'); } function login(){ var username=$("#username").val(); if(username==''){ alert('用户不能为空'); return; } myusername=username; if (typeof (WebSocket) == "undefined") { console.log("遗憾:您的浏览器不支持WebSocket"); } else { console.log("恭喜:您的浏览器支持WebSocket"); //实现化WebSocket对象 //指定要连接的服务器地址与端口建立连接 //注意ws、wss使用不同的端口。我使用自签名的证书测试,无法使用wss,浏览器打开WebSocket时报错 //ws对应http、wss对应https。 socket = new WebSocket("ws://localhost:8082/ws/chat?username=" username); //连接打开事件 socket.onopen = function() { console.log("Socket 已打开"); //socket.send("消息发送测试(From Client)"); $("#loginpage").hide(); $("#chatpage").show(); getOnlineUser(); }; //收到消息事件 socket.onmessage = function(msg) { console.log(msg.data); var message=JSON.parse(msg.data); if(message.to==''){ $("#chatdiv").append("<div class='xitongshuo'>【管理员】" message.from "说:" message.message "</div>"); }else{ $("#chatdiv").append("<div class='othershuo'>" message.from "说:" message.message "</div>"); } }; //连接关闭事件 socket.onclose = function() { console.log("Socket已关闭"); }; //发生了错误事件 socket.onerror = function() { alert("Socket发生了错误"); } //窗口关闭时,关闭连接 window.unload=function() { socket.close(); }; } }</script></body></html>
测试效果截图:
赞 (0)