SpringBoot-实现WebSocket群聊私聊
程序员文章站
2022-10-03 20:22:10
参考博客:https://blog.csdn.net/qq_42240818/article/details/91414670还有一篇参考的,但是我不知道跑哪去了。就没贴了,如果后续找到了,就会贴的。1.添加依赖 org.springframework.boot spring-boot-starter-websocke...
参考博客:https://blog.csdn.net/qq_42240818/article/details/91414670
还有一篇参考的,但是我不知道跑哪去了。就没贴了,如果后续找到了,就会贴的。
1.添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
2.编写配置文件
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
@Configuration
public class WebSocketConfig {
//这个bean会自动注册使用了@ServerEndpoint注解声明的Websocket endpoint
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
3.编写一对一聊天
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.io.IOException;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicInteger;
//{user}、{uuid}这两个值从前端获取
@ServerEndpoint(value = "/onewebsocket/{user}/{uuid}")
@Component
public class oneWebSocket {
// 通过类似GET请求方式传递参数的方法(服务端采用第二种方法"WebSocketHandler"实现)
// websocket = new WebSocket("ws://127.0.0.1:18080/testWebsocket?id=23&name=Lebron");
/**
* 在线人数
*/
public static AtomicInteger onlineNumber = new AtomicInteger(0);
/**
* 所有的对象,每次连接建立,都会将我们自己定义的MyWebSocket存放到List中,
*/
public static List<oneWebSocket> webSockets = new CopyOnWriteArrayList<oneWebSocket>();
/**
* 会话,与某个客户端的连接会话,需要通过它来给客户端发送数据
*/
private Session session;
/**
* 每个会话的用户
*/
private String user;
/**
* 建立连接
*
* @param session
*/
@OnOpen
public void onOpen(Session session, @PathParam("user") String user) {
//用户名判断是否为空
if (user == null || "".equals(user)) {
try {
session.close();
} catch (IOException e) {
e.printStackTrace();
}
return;
}
//在线人数+1
onlineNumber.incrementAndGet();
//遍历整个MyWebSocket里面的用户
for (oneWebSocket myWebSocket : webSockets) {
//判断用户是否重名
if (user.equals(myWebSocket.user)) {
try {
session.close();
} catch (IOException e) {
e.printStackTrace();
}
return;
}
}
//如果确定用户正确
//将session的缓存存入这个用户
this.session = session;
//将user的这个用户
this.user = user;
//WebSocket对象+1
webSockets.add(this);
System.out.println("有新连接加入! 当前在线人数" + onlineNumber.get());
}
/**
* 连接关闭
*/
@OnClose
public void onClose() {
onlineNumber.decrementAndGet();
//移除这个对象
webSockets.remove(this);
System.out.println("有连接关闭! 当前在线人数" + onlineNumber.get());
}
/**
* 收到客户端的消息
*
* @param message 消息
* @param session 会话
*/
@OnMessage
public void onMessage(String message,Session session, @PathParam("user") String user,@PathParam("uuid") String uuid) {
//String[] uuid = message.split(":");
System.out.println("来自" + user + "消息:" + message+" 发给谁:"+uuid);
pushMessage(user, message, uuid);
}
/**
* 发送消息
*
* @param message 消息
*/
public void sendMessage(String message) {
try {
//缓存里面的消息发出去
session.getBasicRemote().sendText(message);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 消息推送
*
* @param message
* @param uuid uuid为空则推送全部人员
*/
public static void pushMessage(String user, String message, String uuid) {
//判断为空则推给所有人
if (uuid == null || "".equals(uuid)) {
//推给所有人
for (oneWebSocket myWebSocket : webSockets) {
myWebSocket.sendMessage(user + ":" + message);
}
} else {
//私聊只有两个人,所以也就是所有人呗,信息发给所有人呗
for (OneWebSocket myWebSocket : webSockets) {
myWebSocket.sendMessage(user + ":" + message);
}
}
}
}
4.一对一前端
<html>
<head>
<meta charset="UTF-8">
<title>Web sockets test</title>
<script type="text/javascript">
var ws;
function login() {
if (!ws) {
var user = document.getElementById("name").value;
var uuid = document.getElementById("onename").value;
console.log("uuid:"+uuid);
try {
//注意端口是否一致
ws = new WebSocket("ws://127.0.0.1:8080/onewebsocket/" + user+"/"+uuid);//连接服务器
ws.onopen = function (event) {
console.log("已经与服务器建立了连接...");
alert("登陆成功,可以开始聊天了")
};
ws.onmessage = function (event) {
console.log("接收到服务器发送的数据..." + event.data);
document.getElementById("info").innerHTML += event.data + "<br>";
};
ws.onclose = function (event) {
console.log("已经与服务器断开连接...");
};
ws.onerror = function (event) {
console.log("WebSocket异常!");
};
} catch (ex) {
alert(ex.message);
}
document.getElementById("login").innerHTML = "退出";
} else {
ws.close();
ws = null;
}
}
//发送信息
function SendData() {
var data = document.getElementById("data").value;
try {
ws.send(data);
} catch (ex) {
alert(ex.message);
}
};
</script>
</head>
<body>
<input id="name" value="" placeholder="用户名">
<button id="login" type="button" onclick="login()" value="">登陆</button>
<br/><br/>
<input id="onename" value="" placeholder="发给谁">
<br/><br/>
<input id="data">
<button type="button" onclick='SendData();'>发送消息</button>
<br/><br/>
<div id="info">
</div>
</body>
</html>
5.运行结果为
聊天结果为:
6.编写群聊
与单独聊天差不多,只是少了一个参数uuid的参数
只是将oneWebSocket改为MyWebSocket
html也由前面的转成后面的
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.io.IOException;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicInteger;
@ServerEndpoint(value = "/websocket/{user}")
@Component
public class MyWebSocket {
// 通过类似GET请求方式传递参数的方法(服务端采用第二种方法"WebSocketHandler"实现)
// websocket = new WebSocket("ws://127.0.0.1:18080/testWebsocket?id=23&name=Lebron");
/**
* 在线人数
*/
public static AtomicInteger onlineNumber = new AtomicInteger(0);
/**
* 所有的对象,每次连接建立,都会将我们自己定义的MyWebSocket存放到List中,
*/
public static List<MyWebSocket> webSockets = new CopyOnWriteArrayList<MyWebSocket>();
/**
* 会话,与某个客户端的连接会话,需要通过它来给客户端发送数据
*/
private Session session;
/**
* 每个会话的用户
*/
private String user;
/**
* 建立连接
*
* @param session
*/
@OnOpen
public void onOpen(Session session, @PathParam("user") String user) {
//用户名判断是否为空
if (user == null || "".equals(user)) {
try {
session.close();
} catch (IOException e) {
e.printStackTrace();
}
return;
}
//在线人数+1
onlineNumber.incrementAndGet();
//遍历整个MyWebSocket里面的用户
for (MyWebSocket myWebSocket : webSockets) {
//判断用户是否重名
if (user.equals(myWebSocket.user)) {
try {
session.close();
} catch (IOException e) {
e.printStackTrace();
}
return;
}
}
//如果确定用户正确
//将session的缓存存入这个用户
this.session = session;
//将user的这个用户
this.user = user;
//WebSocket对象+1
webSockets.add(this);
System.out.println("有新连接加入! 当前在线人数" + onlineNumber.get());
}
/**
* 连接关闭
*/
@OnClose
public void onClose() {
onlineNumber.decrementAndGet();
//移除这个对象
webSockets.remove(this);
System.out.println("有连接关闭! 当前在线人数" + onlineNumber.get());
}
/**
* 收到客户端的消息
*
* @param message 消息
* @param session 会话
*/
@OnMessage
public void onMessage(String message, Session session, @PathParam("user") String user) {
System.out.println("来自" + user + "消息:" + message);
pushMessage(user, message, null);
}
/**
* 发送消息
*
* @param message 消息
*/
public void sendMessage(String message) {
try {
//缓存里面的消息发出去
session.getBasicRemote().sendText(message);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 消息推送
*
* @param message
* @param uuid uuid为空则推送全部人员
*/
public static void pushMessage(String user, String message, String uuid) {
if (uuid == null || "".equals(uuid)) {
//推给所有人
for (MyWebSocket myWebSocket : webSockets) {
myWebSocket.sendMessage(user + ":" + message);
}
} else {
for (MyWebSocket myWebSocket : webSockets) {
//推给某一个人
if (uuid.equals(myWebSocket.user)) {
myWebSocket.sendMessage(message);
}
}
}
}
}
7.群聊前端
<html>
<head>
<meta charset="UTF-8">
<title>Web sockets test</title>
<script type="text/javascript">
var ws;
function login() {
if (!ws) {
var user = document.getElementById("name").value;
try {
//注意端口是否一致
ws = new WebSocket("ws://127.0.0.1:8080/websocket/" + user);//连接服务器
//建立连接 session=event
ws.onopen = function (event) {
console.log("已经与服务器建立了连接...");
alert("登陆成功,可以开始聊天了")
};
//event代表的就是数据,服务器传过来的数据
ws.onmessage = function (event) {
//接收到后台发送过来的数据
console.log("接收到服务器发送的数据..." + event.data);
//界面打印
document.getElementById("info").innerHTML += event.data + "<br>";
};
ws.onclose = function (event) {
console.log("已经与服务器断开连接...");
};
ws.onerror = function (event) {
console.log("WebSocket异常!");
};
} catch (ex) {
alert(ex.message);
}
document.getElementById("login").innerHTML = "退出";
} else {
ws.close();
ws = null;
}
}
//发送信息
function SendData() {
var data = document.getElementById("data").value;
try {
ws.send(data);
} catch (ex) {
alert(ex.message);
}
};
</script>
</head>
<body>
<input id="name" value="" placeholder="用户名">
<button id="login" type="button" onclick="login()" value="">登陆</button>
<br/><br/>
<input id="data">
<button type="button" onclick='SendData();'>发送消息</button>
<br/><br/>
<!--打印数据-->
<div id="info">
</div>
</body>
</html>
附工程结构:
对于运行:
可以直接运行后端,然后再拿浏览器运行前端代码即可。
也可以直接在同一个项目里运行,这个就跑到SpringBoot运行html了。
你们可以看看这篇文章:https://blog.csdn.net/weixin_45969142/article/details/114001188
本文地址:https://blog.csdn.net/weixin_45969142/article/details/114003103
上一篇: SpringMVC的配置与应用
下一篇: 名士贾谊的才能怎么样?他为何得不到重用?