Websocket直播間聊天室教程 GoEasy快速實現(xiàn)聊天室
最近兩年直播那個火啊,真的是無法形容!經(jīng)常有朋友問起,我想實現(xiàn)一個直播間聊天或者我想開發(fā)一個聊天室, 要如何開始呢?

今天小編就手把手的教你用GoEasy做一個聊天室,當(dāng)然也可以用于直播間內(nèi)的互動。全套源碼已經(jīng)開源,git地址: https://gitee.com/goeasy-io/GoEasyDemo-Live-Chatroom.git
本教程主要目的是為大家介紹實現(xiàn)思路,為了確保本教程能幫助到使用不同前端技術(shù)的朋友,采用了HTML + JQuery的方式,后續(xù)還會推出Uniapp(vue/nvue)和小程序版本,大家可以持續(xù)關(guān)注。
我們這次要實現(xiàn)的聊天室,有兩個界面,分別是:
- 登錄界面
- 聊天室界面
登錄

對于登錄界面,我們期望:
- 用戶可以輸入自己的昵稱
- 用戶可以選擇自己喜歡的頭像
- 用戶可以選擇進(jìn)入不同的聊天室(直播間)
實現(xiàn)步驟
登錄界面的實現(xiàn),不用多說,因為真的是So Easy! 一個簡單的界面,只包含三個簡單的邏輯:
驗證是否輸入昵稱
驗證是否選擇一個頭像
根據(jù)選擇進(jìn)入相應(yīng)的聊天室
下邊重點講一下聊天室的實現(xiàn)。
聊天室(直播間)

當(dāng)我們進(jìn)入一個聊天室后,我們期望:
- 用戶能看到當(dāng)前有多少用戶在線,這個數(shù)字能夠?qū)崟r的更新
- 用戶能看到當(dāng)前在線用戶們的頭像,而且能夠?qū)崟r的更新
- 如果有用戶進(jìn)入或離開聊天室
- a. 聊天室會有“XXX進(jìn)來了"或"XXX離開了"的提示
- b. 在線用戶的數(shù)字和用戶的頭像列表會隨之自動更新
- 用戶可以在聊天里發(fā)言
- 用戶可以發(fā)送道具:火箭或者比心
實現(xiàn)步驟
第一步:聊天室界面顯示
1. 初始化:
當(dāng)用戶選擇了一個聊天室,顯示聊天室界面之前,我們首先要進(jìn)行以下初始化工作:
- 初始化當(dāng)前用戶currentUser,用戶id,昵稱,頭像
- 初始化當(dāng)前聊天室ID: currentRoomId
- 初始化GoEasy對象,注意一定要加上userId參數(shù)(可以是該用戶的uuid或id等唯一標(biāo)識,只有設(shè)置了userId的客戶端在上下線時,才會觸發(fā)上下線提醒)。同時需要將頭像和昵稱放入userData,當(dāng)我們收到一個用戶上線提醒的時候,我們需要知道這個用戶的頭像和昵稱。
- 初始化onlineUsers,onlineUsers是用來存放當(dāng)前聊天室在線用戶數(shù)和在線用戶列表。 將當(dāng)前聊天室Id (currentRoomId)作為channel,執(zhí)行g(shù)oEasy.hereNow查詢此刻聊天室在線用戶數(shù)和用戶列表,賦值給onlineUsers。除了在進(jìn)入聊天室的時候初始化onlineUsers,當(dāng)有用戶進(jìn)入或離開時,也會動態(tài)的更新onlineUsers。
- 以當(dāng)前聊天室的id(currentRoomId)作為channel,執(zhí)行subscriber方法監(jiān)聽和接收聊天室新消息。
- 以當(dāng)前聊天室的id(currentRoomId)作為channel,執(zhí)行subscriberPresence監(jiān)聽用戶進(jìn)入和離開事件。
參考代碼:service.js
//初始化聊天室
this.joinRoom = function(userId,nickName, avatar, roomID) {
//初始化當(dāng)前用戶
this.currentUser = new User(userId, nickName, avatar);
//初始化當(dāng)前聊天室id
this.currentRoomId = roomID;
//初始化goeasy,建立長連接
this.goeasy = new GoEasy({
host: "hangzhou.goeasy.io",
appkey: "您的appkey",
userId: this.currentUser.id,
userData: '{"nickname":"' + this.currentUser.nickname + '","avatar":"' + this.currentUser.avatar + '"}',
onConnected: function () {
console.log( "GoEasy connect successfully.")
},
onDisconnected: function () {
console.log("GoEasy disconnected.")
}
});
//查詢當(dāng)前在線用戶列表,初始化onlineUsers對象
this.initialOnlineUsers();
//監(jiān)聽用戶上下線提醒,實時更新onlineUsers對象
this.subscriberPresence();
//監(jiān)聽和接收新消息
this.subscriberNewMessage();
};
2. 頁面展示:
完成初始化之后,就跳轉(zhuǎn)到直播間界面,在頁面上顯示以下數(shù)據(jù):
- 當(dāng)前聊天室的名稱
- 聊天記錄,并且顯示聊天室界面
- 展示聊天室界面
參考代碼:controller.js
//頁面切換到聊天室界面
function showChatRoom() {
//更新房間名
$("#chatRoom-header").find(".current-chatRoom-name").text(loginCommand.roomName);
//加載聊天歷史
var chatHistory = service.loadChatHistory();
chatHistory.forEach(function (item) {
//展示發(fā)送的消息
var otherPerson = createCurrentChatRoomPerson(item.senderNickname + ":", item.content)
$(".chatRoom-content-box").append($(otherPerson));
});
//隱藏登錄界面
$(".chat-login-box").hide();
// //顯示聊天界面
$(".chatRoom-box").show();
// //滑動到最后一行
scrollBottom();
}
至此,我們已經(jīng)完成了goeasy長連接的初始化,和一個聊天室靜態(tài)展示。接下來,我們一起來看看如何讓這個聊天室能夠動起來。
第二步:聊天室互動
1. 實時更新在線用戶數(shù)和頭像列表
之前在service.initialOnlineUsers方法已經(jīng)初始化onlineUsers對象,但聊天室隨時都有用戶進(jìn)進(jìn)出出,所以我們接下來還需要能夠在有用戶上線或下線的時候能夠?qū)崟r的更新onlineUsers,并且實時顯示在頁面上。 當(dāng)我們收到一個用戶上線提醒,我們將新上線的用戶的信息存入在線用戶對象onlineUsers里,當(dāng)有用戶離開時,在本地在線用戶列表里刪除。
參考代碼:service.js
//監(jiān)聽用戶上下線時間,維護(hù)onlineUsers對象
this.subscriberPresence = function() {
var self = this;
this.goeasy.subscribePresence({
channel: this.currentRoomId,
onPresence: function(presenceEvents) {
presenceEvents.events.forEach(function(event) {
var userId = event.userId;
var count = presenceEvents.clientAmount;
//更新onlineUsers在線用戶數(shù)
self.onlineUsers.count = count;
//如果有用戶進(jìn)入聊天室
if (event.action == "join" || event.action == "online") {
var userData = JSON.parse(event.userData);
var nickName = userData.nickname;
var avatar = userData.avatar;
var user = new User(userId, nickName, avatar);
//將新用戶加入onlineUsers列表
self.onlineUsers.users.push(user);
//觸發(fā)界面的更新
self.onJoinRoom(user.nickname, user.avatar);
} else {
for (var i = 0; i < self.onlineUsers.users.length; i++) {
var leavingUser = self.onlineUsers.users[i];
if (leavingUser.id == userId) {
var nickName = leavingUser.nickname;
var avatar = leavingUser.avatar;
//將離開的用戶從onlineUsers中刪掉
self.onlineUsers.users.splice(i, 1);
//觸發(fā)界面的更新
self.onLeaveRoom(nickName, avatar);
}
}
}
});
},
onSuccess : function () {
console.log("監(jiān)聽成功")
},
onFailed : function () {
console.log("監(jiān)聽失敗")
}
});
};
2. 發(fā)送消息
- 初始化一個chatMessage對象,包含發(fā)送方id,昵稱,消息內(nèi)容,消息類型為chat
- 將chatMessage轉(zhuǎn)換為一個Json格式的字符串
- 調(diào)用GoEasy的Publish方法,完成消息的發(fā)送
參考代碼(service.js)
this.sendMessage = function(content) {
var message = new ChatMessage(this.currentUser.id,this.currentUser.nickname, MessageType.CHAT, content);
var self = this;
this.goeasy.publish({
channel: self.currentRoomId,
message: JSON.stringify(message),
onSuccess: function() {
console.log("消息發(fā)布成功。");
},
onFailed: function(error) {
console.log("消息發(fā)送失敗,錯誤編碼:" + error.code + " 錯誤信息:" + error.content);
}
});
};
3. 接收和顯示新消息/道具
之前我們已經(jīng)在初始化頁面的時候執(zhí)行了service.subscriberNewMessage(),當(dāng)我們收到一條消息時:
- 根據(jù)消息類型判斷是一條聊天消息,還是一個道具
- 如果收到的是一條聊天消息,直接顯示到界面
- 如果是道具,就播放動畫
參考代碼(service.js)
//監(jiān)聽消息或道具
this.subscriberNewMessage = function() {
var self = this;
this.goeasy.subscribe({
channel: this.currentRoomId, //替換為您自己的channel
onMessage: function(message) {
var chatMessage = JSON.parse(message.content);
//todo:事實上不推薦在前端收到時保存, 一個用戶開多個窗口,會導(dǎo)致重復(fù)保存, 建議所有消息都是都在發(fā)送時在服務(wù)器端保存,這里只是為了演示
self.restapi.saveChatMessage(self.currentRoomId, chatMessage);
//如果收到的是一個消息,就顯示為消息
if (chatMessage.type == MessageType.CHAT) {
var selfSent = chatMessage.senderUserId == self.currentUser.id;
var content = JSON.parse(message.content);
self.onNewMessage(chatMessage.senderNickname, content, selfSent);
}
//如果收到的是一個道具,就播放道具動畫
if (chatMessage.type == MessageType.PROP) {
if (chatMessage.content == Prop.ROCKET) {
self.onNewRocket(chatMessage.senderNickname);
}
if (chatMessage.content == Prop.HEART) {
self.onNewHeart(chatMessage.senderNickname);
}
}
}
});
};
4. 發(fā)送和接收并展示道具
其實和發(fā)送消息的實現(xiàn)幾乎是一樣的,具體代碼請參考service.js的sendProp方法,controller.js的onNewHeart()方法。動畫的播放,使用了TweenMax這個庫,主要是為了展示一個實現(xiàn)思路,小編也不知道這個庫是否有很好的兼容性,以及是否能夠用在Uniapp和小程序下,知道的朋友可以留言分享給大家。
this.sendProp = function(prop) {
var self = this;
var message = new ChatMessage(this.currentUser.id,this.currentUser.nickname, MessageType.PROP, prop);
this.goeasy.publish({
channel: self.currentRoomId,
message: JSON.stringify(message),
onSuccess: function() {
console.log("道具發(fā)布成功。");
},
onFailed: function(error) {
console.log("道具發(fā)送失敗,錯誤編碼:" + error.code + " 錯誤信息:" + error.content);
}
});
};
至此,一個聊天室就搞定了,是不是很簡單?
總結(jié)
到此這篇關(guān)于Websocket直播間聊天室教程 GoEasy快速實現(xiàn)聊天室的文章就介紹到這了,更多相關(guān)Websocket聊天室內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
VsCode中ctrl+s后會在當(dāng)前目錄下自動生成dist目錄的方法
這篇文章主要介紹了VsCode中ctrl+s后會在當(dāng)前目錄下自動生成dist目錄,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-09-09
Jenkins定時構(gòu)建語法規(guī)則及時間設(shè)置
這篇文章主要為大家介紹了Jenkins定時構(gòu)建時間設(shè)置,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06

