WebSocket ,HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议,其使用简单,应用场景也广泛,不同开发语言都用种类繁多的实现,仅Java体系中,Tomcat,Jetty,Spring等都提供了对WS的API支持。本篇不做理论探究,仅自娱自乐,简单实现网页版的聊天室功能,在实际开发场景中变通使用即可。废话不叽歪,直接撸出来——
1 简单页面
代码语言:javascript复制<!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 "rn");
}
</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 后端实现
代码语言:javascript复制/**
* @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 ":rn" 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);
}
}
}