WebSocket ,HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议,其使用简单,应用场景也广泛,不同开发语言都用种类繁多的实现,仅Java体系中,Tomcat,Jetty,Spring等都提供了对WS的API支持。本篇不做理论探究,仅自娱自乐,简单实现网页版的聊天室功能,在实际开发场景中变通使用即可。废话不叽歪,直接撸出来——
1 简单页面
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>HanppyRoom</title> <script> var url = "ws://" + window.location.host + "/page_room/"; var ws = null; //加入聊天室 function joinRoom() { if (ws) { alert("你已经在聊天室,不能再加入"); return; } var username = document.getElementById("user").value; ws = new WebSocket(url + username); //与服务端建立连接触发 ws.onopen = function () { console.log("与服务器成功建立连接") }; //服务端推送消息触发 ws.onmessage = function (ev) { talking(ev.data); }; //发生错误触发 ws.onerror = function () { console.log("连接错误") }; //正常关闭触发 ws.onclose = function () { console.log("连接关闭"); }; } //退出聊天室 function exitRoom() { closeWebSocket(); } function sendMsg() { if(!ws){ alert("你已掉线,请重新加入"); return; } //消息发送 ws.send(document.getElementById("sendMsg").value); document.getElementById("sendMsg").value = ""; } function closeWebSocket() { if(ws){ ws.close(); ws = null; } } function talking(content) { document.getElementById("content").append(content + "\r\n"); } </script> </head> <body> <div style="text-align: center;background-color: rgba(129,86,255,0.35);margin:0 auto;border:1px solid #000;width:600px;height:650px"> <br>欢迎使用<strong>陈本布衣</strong>牌极简聊天室:<br/><br/> <textarea id="content" cols="60" rows="30" readonly="readonly"></textarea><br> <input type="text" id="sendMsg"> <button type="button" onclick="sendMsg()">发送消息</button> <br/><br/> 用户:<input type="text" id="user"> <button onclick="joinRoom()">加入群聊</button> <button onclick="exitRoom()">退出群聊</button> </div> </body> </html>
2 后端实现
/** * @ServerEndpoin 注解声明该类为 WebSocket 的服务端端点 * value 值为监听客户端访问的 URL */ @ServerEndpoint(value = "/page_room/{username}") public class WsByTomcat { //这里只是简单测试用,真正的场景请考虑线程安全的容器或其它并发解决方案 private static List<Session> sessions = new ArrayList<>(); /** * @param session 与客户端的会话对象【可选】 * @param username 路径参数值 【可选】 * @throws IOException * @OnOpen 标注此方法在 ws 连接建立时调用,可用来处理一些准备性工作 可选参数 * EndpointConfig(端点配置信息对象) Session 连接会话对象 */ @OnOpen public void OnOpen(Session session, @PathParam("username") String username) throws IOException { sessions.add(session); sendTextMsg("好友 [" + username + "] 加入群聊"); } /** * @param msg 接受客户端消息 * @param username RESTful 路径方式获取用户名 * @throws IOException * @OnMessage 在收到客户端消息调用 消息形式不限于文本消息,还可以是二进制消息(byte[]/ByteBuffer等),ping/pong 消息 */ @OnMessage public void OnMsg(String msg, @PathParam("username") String username) throws IOException { sendTextMsg(username + ":\r\n" + msg); } /** * @OnClose 连接关闭调用 */ @OnClose public void OnClose(Session session, @PathParam("username") String username) throws IOException { sessions.remove(session); sendTextMsg("好友 ["+username + "] 退出群聊"); } /** * @param e 异常参数 * @OnError 连接出现错误调用 */ @OnError public void OnError(Throwable e) { e.printStackTrace(); } private void sendTextMsg(String msg) { for (Session session : sessions) { session.getAsyncRemote().sendText(msg); } } }
3 3P聊天效果
作者:陈本布衣
本文版权归作者和博客园共有,欢迎转载分享,但必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利。