1.依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
2.WebSocket配置
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
/**
* WebSocket 配置
*/
@Configuration
@EnableWebSocket
public class WebSocketStompConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter()
{
return new ServerEndpointExporter();
}
}
3.websocket服务
package com.cq.zxgytx.runing.controller.websoket;
import com.cq.zxgytx.runing.entity.SocketEntity;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.HashSet;
import java.util.Set;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@Slf4j
@Component
@ServerEndpoint("/webSocket/chat/{roomId}/{userId}")
public class WsServer {
// 使用map来收集session,key为roomId,value为同一个房间的用户集合
// concurrentMap的key不存在时报错,不是返回null
private static final Map<String, Set<SocketEntity>> websockets = new ConcurrentHashMap();
@OnOpen
public void connect(@PathParam("roomId") String roomId,@PathParam("userId") String userId, Session session) throws Exception {
// 将session按照房间名来存储,将各个房间的用户隔离
if (!websockets.containsKey(roomId)) {
// 创建房间不存在时,创建房间
Set<SocketEntity> set = new HashSet<>();
// 添加用户
SocketEntity socket1=new SocketEntity();
socket1.setSession(session).setUserId(userId);
set.add(socket1);
websockets.put(roomId, set);
//messageType 1代表上线 2代表下线 3代表在线名单 4代表普通消息
//先给所有人发送通知,说我上线了
broadcast(roomId,userId+"上线了");
} else {
// 添加用户
SocketEntity socket=new SocketEntity();
socket.setSession(session).setUserId(userId);
// 房间已存在,直接添加用户到相应的房间
websockets.get(roomId).add(socket);
broadcast(roomId,userId+"上线了");
}
log.info(userId+"加入房间--"+roomId+"! 当前在线人数" + websockets.get(roomId).size());
}
/**
* 关闭聊天房间
* @param roomId
* @param userId
*/
@OnClose
public void disConnect(@PathParam("roomId") String roomId,@PathParam("userId") String userId) throws Exception {
removeUser(roomId,userId);
broadcast(roomId,userId+"下线了");
log.info(userId+"退出房间--"+roomId+"! 当前在线人数" + websockets.get(roomId).size());
if(websockets.get(roomId).size()<1){//房间中没有用户了 关闭房间
websockets.remove(roomId);
log.info("房间"+roomId+"关闭");
}
}
@OnMessage
public void receiveMsg(@PathParam("roomId") String roomId,@PathParam("userId") String userId,
String msg, Session session) throws Exception {
// 此处应该有html过滤
msg = session.getId() +userId+ ":" + msg;
log.info(msg);
// 接收到信息后进行广播
broadcast(roomId, msg);
}
// 按照房间名进行广播
public static void broadcast(String roomId, String msg) throws Exception {
for (SocketEntity socketEntity : websockets.get(roomId)) {
socketEntity.getSession().getBasicRemote().sendText(msg);
}
}
/**
* 删除用户
* @param userId
*/
private void removeUser(@PathParam("roomId") String roomId,@PathParam("userId") String userId) {
Set<SocketEntity> set=websockets.get(roomId);
SocketEntity entity = getUserEntity(roomId,userId);
set.remove(entity);
}
/**
* 获取用户
* @param userId
* @return
*/
private static SocketEntity getUserEntity(String roomId,String userId) {
SocketEntity entity = null;
if (websockets.size() == 0) {
return entity;
}
for (SocketEntity socketEntity : websockets.get(roomId)) {
if (socketEntity.getUserId().contentEquals(userId)) {
entity = socketEntity;
break;
}
}
return entity;
}
}
4.SocketEntity
import lombok.Data;
import lombok.experimental.Accessors;
import javax.websocket.Session;
import java.io.Serializable;
/**
* socket 实体类
*/
@Accessors(chain=true)
@Data
public class SocketEntity implements Serializable {
private String userId;//用户id
private Session session;
}
5.前端room.html
<!DOCTYPE html><html lang="en">
<head>
<meta charset="UTF-8">
<title>网络聊天室</title>
</head>
<style type="text/css">
.msg_board {
width: 322px;
height: 100px;
border: solid 1px darkcyan;
padding: 5px;
overflow-y: scroll;
// 文字长度大于div宽度时换行显示
word-break: break-all;
}
/*set srcoll start*/
::-webkit-scrollbar
{
width: 10px;
height: 10px;
background-color: #D6F2FD;
}
::-webkit-scrollbar-track
{
-webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3);
/*border-radius: 5px;*/
background-color: #D6F2FD;
}
::-webkit-scrollbar-thumb
{
height: 20px;
/*border-radius: 10px;*/
-webkit-box-shadow: inset 0 0 6px rgba(0,0,0,.3);
background-color: #89D7F7;
}
/*set srcoll end*/
</style>
<body>
<label>房间ID</label>
<input id="input_roomName" size="10" maxlength="10"><br/>
<label>用户ID</label>
<input id="input_userName" size="10" maxlength="10">
<button type="submit" id="join">进入聊天室</button>
<button type="submit" id="out">退出聊天室</button><br>
<div class="msg_board"></div>
<input id="input_msg" size="43" maxlength="40">
<button type="submit" id="send">发送</button>
</body>
<script src="js/jquery-1.9.1.min.js"/>
<script src="js/swiper.min.js"></script>
<script type="text/javascript">
var webSocket;
$("#send").click( function send_msg() {
if (webSocket != null) {
var input_msg = document.getElementById("input_msg").value.trim();
if (input_msg == "") {
return;
}
webSocket.send(input_msg);
// 清除input框里的信息
document.getElementById("input_msg").value = "";
} else {
alert("您已掉线,请重新进入聊天室...");
}
});
$("#out").click(function closeWs() {
webSocket.close();
});
$("#join").click(function initWebSocket() {
var roomId = document.getElementById("input_roomName").value;
var userId = document.getElementById("input_userName").value;
// 房间名不能为空
if (roomId == null || roomId == "") {
alert("请输入房间ID");
return;
}
if (userId == null || userId == "") {
alert("请输入用户ID");
return;
}
if ("WebSocket" in window) {
// alert("您的浏览器支持 WebSocket!");
if (webSocket == null) {
var url = "ws://localhost:8001/webSocket/chat/" + roomId+"/"+userId;
// 打开一个 web socket
webSocket = new WebSocket(url);
} else {
alert("您已进入聊天室...");
}
webSocket.onopen = function () {
alert("已进入聊天室,畅聊吧...");
};
webSocket.onmessage = function (evt) {
var received_msg = evt.data;
console.log("数据已接收:" +received_msg);
var obj = received_msg;
setMessageInnerHTML(obj);
};
webSocket.onclose = function () {
// 关闭 websocket,清空信息板
alert("连接已关闭...");
webSocket = null;
document.getElementsByClassName("msg_board")[0].innerHTML = "";
};
}
else {
// 浏览器不支持 WebSocket
alert("您的浏览器不支持 WebSocket!");
}
})
//将消息显示在网页上
function setMessageInnerHTML(innerHTML) {
var msg_board=document.getElementsByClassName("msg_board")[0];
msg_board.innerHTML += innerHTML + '<br/>';
// 让滚动块往下移动
msg_board.scrollTop = msg_board.scrollTop + 40;
}
</script>
</html>