部分代码
首先创建springboot项目并引入依赖:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
服务端核心代码
@Component
@ServerEndpoint("/chat/lobby")
public class LobbyChat {
@OnOpen
public void onOpen(Session session) throws IOException {
User user = new User(URLDecoder.decode(session.getQueryString().split("=")[1],"UTF-8"),session);
Info.addUser(user);
for (User u: Info.getUserList()) {
send(u.getSession(),MsgHelper.generateUserInfo(Info.getUserList()));
}
System.out.println("一名用户上线,"+user.toString()+"当前在线人数为:"+ Info.getOnlineCount());
}
@OnClose
public void onClose(Session session) throws IOException {
System.out.println("用户"+Info.getUser(session)+"已下线,当前在线人数:"+(Info.getOnlineCount()-1));
Info.removeUser(session);
for (User u: Info.getUserList()) {
send(u.getSession(),MsgHelper.generateUserInfo(Info.getUserList()));
}
}
@OnError
public void onError(Session session, Throwable error){
System.out.println("发生错误!");
error.printStackTrace();
}
@OnMessage
public void onMessage(String msg,Session session) throws IOException {
ObjectMapper objectMapper = new ObjectMapper();
Map<String,String> received = objectMapper.readValue(msg, new TypeReference<Map<String,String>>(){});
String msgObj = null;
User sender = Info.getUser(session);
if (received.get("type").equals("lobby")){
System.out.println("用户"+Info.getUser(session)+"发出的消息:"+received.get("content"));
msgObj = MsgHelper.generateUserMsg(sender.getUsername(),sender.getSession().getId(),"lobby",received.get("content"));
for (User u: Info.getUserList()) {
send(u.getSession(),msgObj);
}
}
if (received.get("type").equals("friend")){
System.out.println(received);
msgObj = MsgHelper.generateUserMsg(sender.getUsername(),sender.getSession().getId(),"friend",received.get("content"));
send(Info.getUser(received.get("sessionID")).getSession(),msgObj);
}
}
public static void send(Session receiver,String msg) throws IOException {
receiver.getBasicRemote().sendText(msg);
}
}
前端核心代码:
let app = Vue.createApp({
data(){
return {
username:"",
lobby_input:"hello",
friend_input:"",
msg_records_f: [],
msg_records_l:[],
received_msg_f: "",
online_count: 0,
onlineUsers:null,
pri_chat_obj: {username:"未开始私聊",sessionId:-1},
socket: null,
btnChatMovedActiveIndex: -1,
}
},
methods:{
sendMsgToF(){
if(this.pri_chat_obj.sessionId != -1){
if(this.friend_input!=""){
console.log(this.msgObjF);
this.socket?.send(this.msgObjF);
let d= new Date();
let timeStr = d.getHours() + "时" + d.getMinutes() +"分" + d.getSeconds() + "秒";
this.msg_records_f.push({sender:this.username,time:timeStr,content:this.friend_input});
this.friend_input = "";
}
}else {
alert("请先选择私聊对象");
}
},
sendMsgToL(){
if (this.lobby_input !== ""){
this.socket?.send(this.msgObjL);
this.lobby_input = "";
}
},
chatWith(user){
if(user!==this.pri_chat_obj){
this.pri_chat_obj = user;
this.msg_records_f = [];
}
},
getUserBySessionID(id){
for (let i = 0; i < this.onlineUsers.length; i++) {
if (this.onlineUsers[i].sessionId === id){
return this.onlineUsers[i];
}
}
}
},
computed:{
msgObjL(){
return JSON.stringify({type:"lobby",content:this.lobby_input});
},
msgObjF(){
return JSON.stringify({type:"friend",sessionID:this.pri_chat_obj.sessionId,content:this.friend_input});
}
},
watch:{
received_msg_f(val){
console.log(val)
}
},
mounted(){
let name = window.prompt("请输入你在本次聊天中要使用的昵称");
while (name === ""||name == null){
name = window.prompt("请输入一个昵称!");
}
this.username = name;
let webSocket = new WebSocket("ws://127.0.0.1:8080/chat/lobby?username="+this.username);
webSocket.onopen = function (){
console.log("链接建立成功");
app.$data.socket = webSocket;
}
webSocket.onclose = function (){
console.log("连接已关闭");
}
webSocket.onerror = function (err){
alert("连接服务器失败!");
console.log(err);
}
webSocket.onmessage = function (event){
console.log(event.data)
let msgObj = JSON.parse(event.data);
console.log(msgObj)
if(msgObj.type==="message"){
if(msgObj.to==="lobby"){
app.$data.msg_records_l.push(msgObj);
}
if (msgObj.to==="friend"){
app.$data.msg_records_f.push(msgObj);
app.$data.pri_chat_obj = app.getUserBySessionID(msgObj.senderID);
}
}
if (msgObj.type=="info"){
app.$data.online_count = msgObj.onlineCount;
app.$data.onlineUsers = msgObj.userList;
}
}
window.onbeforeunload = function (){
webSocket.close();
app.$data.socket = null;
app.$data.online_count--;
}
}
}).mount("#app");
完整代码可在Gitee查看.
演示
先输入要使用的昵称 同样方法打开三个标签页 在大厅大消息所有人都会收到 鼠标在在线者列表上悬浮会出现chat按钮,点击可开始私聊 向私聊对象发送消息,只有他一个人会收到,Tony收到消息 Thor没有收到 Peter收到Tony的回复
|