项目目录
WebScoket包
<!-- https://mvnrepository.com/artifact/javax.websocket/javax.websocket-api -->
<dependency>
<groupId>javax.websocket</groupId>
<artifactId>javax.websocket-api</artifactId>
<version>1.1</version>
<scope>provided</scope>
</dependency>
json包
<!-- https://mvnrepository.com/artifact/org.json/json -->
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20180130</version>
</dependency>
<!DOCTYPE html>
<html lang="en" style="height:100%">
<head>
<meta charset="UTF-8">
<title>基于WebSocket的聊天室</title>
</head>
<body style="height:100%">
登录名:<input type="text" id="username" placeholder="登录名">
<input type="button" value="连接" id="login">
<input type="button" value="断开" id="logout" onclick="closeWebSocket()">
<div id="message_0">欢迎来到聊天室!</div>
<div id="messages"></div>
<div id="inputMessage" style="position:absolute;bottom:0">
To: <input type="text" id="toUsername" value="All" style="width:5em"/>
<input type="button" name="sendMessage" id="sendMessage" value="发送" onclick="sendMessage()">
<br>
<textarea name="message" id="message" cols="30" rows="10"></textarea>
</div>
</body>
<script type="text/javascript">
// websocket对象
var websocket = null;
// 消息列表元素
var messages = document.getElementById("messages");
// 登陆按钮的事件
document.getElementById("login").addEventListener("click", function () {
var username = document.getElementById("username").value;
if (username == "") {
return false;
}
// 判断浏览器是否支持WebSocket
if (("WebSocket" in window)) {
websocket = new WebSocket("ws://" + document.location.host + "/websocket/" + username);
/*
* WebSocket连接成功事件
*/
websocket.onopen = function () {
setInfoMessage("WebScoket连接成功。");
}
/*
* WebSocket接收到消息
*/
websocket.onmessage = function (event) {
var div = document.createElement("div");
div.innerText = event.data;
messages.appendChild(div)
}
/*
* WebSocket断开连接事件
*/
websocket.onclose = function () {
setInfoMessage("WebScoket连接关闭。");
}
/*
* WebSocket异常事件
*/
websocket.onerror = function () {
setInfoMessage("WebSocket连接异常。")
}
/*
* 监听窗口离开事件,关闭websocket连接
*/
window.onbeforeunload = function () {
closeWebSocket();
}
}
else {
setInfoMessage("当前浏览器不支持WebSocket!");
}
})
/*
* 向服务器发送消息
*/
function sendMessage() {
if (websocket) {
// 获取消息内容
var messageContent = document.getElementById("message").value;
// 获取目标用户
var toUsername = document.getElementById("toUsername").value;
// 构建json格式的消息对象
var message = "{"
+ "To:" + toUsername+ ","
+ "Message: " + messageContent
+ "}"
// 发送消息
websocket.send(message);
}
else {
setInfoMessage("WebSocket未连接。")
}
}
//关闭连接
function closeWebSocket() {
if (websocket) {
websocket.close();
}
else {
setInfoMessage("WebSocket未连接。")
}
}
function setInfoMessage(message) {
document.getElementById("message_0").innerText = message;
}
</script>
</html>
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* @ServerEndpoint注解是websocket的核心注解 作为类层次的注解,它将目标类定义成一个websocket服务器端
* 注解的值将被用于监听客户端访问的URL地址,用户可以通过该URL访问websocket服务器端
* 用户用username标注
*/
@ServerEndpoint("/websocket/{username}")
public class WebSocketTest1 {
// 用户名
private String username;
// 和客户端的连接会话
private Session session;
// 用一个线程安全的map记录每个客户对应的WebSocket
private static Map<String, WebSocketTest1> clients
= new ConcurrentHashMap<String, WebSocketTest1>();
/**
* 连接成功调用的函数
*
* @param username 用户名
* @param session 和客户端的会话
*/
@OnOpen
public void onOpen(@PathParam("username") String username, Session session) {
this.username = username;
this.session = session;
clients.put(username, this);
sendMessageAll(username + "已连接!当前在线人数:" + clients.size());
System.out.println(username + "已连接!");
}
/**
* 连接关闭时执行的函数
*
* @throws IOException
*/
@OnClose
public void onClose() throws IOException {
clients.remove(username);
sendMessageAll(username + "断开连接!当前在线人数:" + clients.size());
}
/**
* 接收到消息时执行的函数
*
* @param message 接受的消息内容
* @throws IOException
*/
@OnMessage
public void onMessage(String message, Session session) throws IOException {
JSONObject jsonTo = new JSONObject(message);
if (!jsonTo.get("To").equals("All")) {
message = this.username + "对你说:" + jsonTo.get("Message");;
sendMessageTo(message, jsonTo.get("To").toString());
} else {
message = this.username + "说:" + jsonTo.get("Message");
sendMessageAll(message);
}
}
/**
* 发生错误执行的函数
* @param session
* @param error
*/
@OnError
public void onError(Session session, Throwable error) {
error.printStackTrace();
}
/**
* 向目标用户发送消息
*
* @param message 消息内容
* @param to 目标用户
* @throws IOException
*/
private void sendMessageTo(String message, String to) throws IOException {
for (WebSocketTest1 item : clients.values()) {
if (item.username.equals(to)) {
item.session.getAsyncRemote().sendText(message);
}
}
}
/**
* 向所有人发送消息
*
* @param message 消息内容
*/
private void sendMessageAll(String message) {
for (WebSocketTest1 item : clients.values()) {
item.session.getAsyncRemote().sendText(message);
}
}
}
运行结果