定义一个WebSocket类
- @ServerEndpoint:标记为一个WebSocket类,value指定url地址,可以通过{name}获取参数name值
- @OnOpen、@OnClose、@OnMessage:连接、关闭、接收消息
- Session:与某个客户端的连接会话,使用session.getBasicRemote().sendText()给客户端发送数据
- Map<String, ChatSocket>:使用Map集合维护多个客户端连接集合,在连接成功时加入,连接断开时删除
import java.io.IOException;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
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;
@ServerEndpoint(value = "/ws/chat/{username}")
public class ChatSocket {
// 使用session对用户发送数据
private Session session;
private String name;
// 客户端连接集合
private static Map<String, ChatSocket> users = new ConcurrentHashMap<>();
/**
* 客户端连接
* @param session
* @throws IOException
*/
@OnOpen
public void open(Session session, @PathParam("username")String username) throws IOException{
this.session = session; //每次客户端连接重置当前session
this.name = username;
users.put(username, this);//增加用户连接
// 更新在线人数
String messageFormat = "{"msg":"%s","total":%d}";
for (ChatSocket chat : users.values()){
Date date = new Date();
chat.sendMessage(String.format(messageFormat, date.toString()+" "+username+" 登入", users.size()));
}
}
/**
* 客户端关闭
* @param session
* @throws IOException
*/
@OnClose
public void close(Session session) throws IOException{
//this.username = username;
users.remove(name); // 删除指定用户的key
// 更新在线人数
String messageFormat = "{"msg":"%s","total":%d}";
for (ChatSocket chat : users.values()){
Date date = new Date();
chat.sendMessage(String.format(messageFormat, date.toString()+" "+name+" 退出", users.size()));
}
}
/**
* 连接错误
* @param e
*/
@OnError
public void error(Session s, Throwable e){
e.printStackTrace();
}
/**
* 接受客户端发送来的消息
* @throws IOException
*/
@OnMessage
public void recMessage(String message, Session session) throws IOException{
String messageFormat = "{"msg":"%s","total":%d}";
for (ChatSocket chat : users.values()){
Date date = new Date();
chat.sendMessage(String.format(messageFormat, date.toString()+"| "+name+" : "+message, users.size()));
}
}
/**
* 向客户端发送消息
* @param message
* @throws IOException
*/
public void sendMessage(String message) throws IOException{
session.getBasicRemote().sendText(message);
}
}
和前端交互
- new WebSocket("url"):生成WebSocket对象
- window.onbeforeunload:监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常
- if ('WebSocket' in window):判断浏览器是否支持WebSocket
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Insert title here</title>
<script src="//cdn.bootcss.com/jquery/1.11.3/jquery.min.js"></script>
</head>
<body>
online number:<div id="num"></div><br/>
<input type="text" id="username" /> <input type="button" id="connect" title="connect" value="connect" onclick="getConnetion()"><br/>
<input type="text" id="content" /> <br/>
<input type="button" id="send" title="send" value="send" onclick="sendMsg()">
<div id="msg"></div>
<script type="text/javascript">
var websocket = null;
function getConnetion(){
var name = $("#username").val();
if ('WebSocket' in window){
if (websocket == null){
websocket = new WebSocket("ws://localhost:8080/bitcoin/ws/chat/"+name);
// 连接成功回掉
websocket.onopen = function(){
//websocket.send("客户端连接成功");
}
// 接收到消息的回掉方法
websocket.onmessage = function(event){
recvMessage(event.data);
}
// 连接发生错误的回调方法
websocket.onerror = function () {
alert("WebSocket连接发生错误");
};
// 连接关闭的回调方法
websocket.onclose = function () {
alert("WebSocket连接关闭");
}
}
}
}
//监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
window.onbeforeunload = function () {
closeWebSocket();
}
// 关闭WebSocket连接
function closeWebSocket() {
websocket.close();
}
// 监听消息发送
function sendMsg(){
var con = $("#content").val();
if (null != websocket){
websocket.send(con);
}
}
// 接收到服务器消息
function recvMessage(innerHTML){
var msg = eval("("+innerHTML+")");
$("#num").html(msg.total);
$("#msg").append("<div>"+msg.msg+"</div><br/>");
}
</script>
</body>
</html>