*不管名稱為何,只要 client發送渠道名稱 = server接收渠道名稱 or server發送渠道名稱 = client接收渠道名稱,就能夠做到一發一收!!!!!!!!!!!(詳情看夏方程式碼)
頁面:ChatPublic.vue
路由:/chat/public
通道 - 拿到歷史訊息:
messages(發) >> messages(收)getAllMessages(發) >> getAllMessages(收)
client端發出通道請求:
// Vue created時觸發
this.$socket.emit('messages')
server端監聽並回覆請求:
socket.on('messages', () => {
// 從資料庫拿出所有歷史訊息
const allMessages = ...
socket.emit('getAllMessages', allMessages)
})
client端接收:
sockets: {
getAllMessages(data) {
// 這邊data就是全部歷史訊息的陣列惹~
// 存進data()中,並觸發渲染
}
}
通道 - 多人通信:
sendPublic(發) >> sendPublic(收)receivePublic(發) >> receivePublic(收)
client端發出通道請求: // 這邊改成sendPublic好像比較直白
this.$socket.emit('sendPublic', {
userId: 1
text: '沒有不能解決的問題',
})
server端回監聽並覆請求:
socket.on('sendPublic', (data) => {
const publicMessage = {
userId: 1,
userName: 'Ether',
userAvatar: 'url',
text: '沒有不能解決的問題'
}
io.sockets.emit('receivePublic', publicMessage)
})
client端接收:
sockets: {
receivePublic(data) {
// 這邊data就是某位使用者傳送的一則訊息資訊~
// 存進data()中,並觸發渲染
// 把data拿出來判斷 userId === currentUser.id ?
}
}
通道 - 取得線上使用者:
getUsers(發) >> getUsers(收)receiveUsers(發) >> receiveUsers(收)
client端發出通道請求:
// 進入公開聊天室時觸發
this.$socket.emit('getUsers')
server端回監聽並覆請求:
socket.on('getUsers', () => {
// 撈線上使用者的資料
const users = [
id,
name,
avatar,
account
},{},{}....]
// 發回給傳訊者
socket.emit('receiveUsers', users)
})
client端接收:
sockets: {
receiveUsers(data) {
// 接收到事件就 assign 到 onlineUsers 陣列中
}
}
通道 - 上線事件:
sendOnline(發) >> sendOnline(收)receiveOnline(發) >> receiveOnline(收)
client端發出通道請求:
// signin 時觸發
this.$socket.emit('sendOnline', {
userId: 1
})
server端回監聽並覆請求:
const
socket.on('sendOnline', (data) => {
// 取得socket.id,私訊要用到
const socketId = socket.id
// 在線上使用者資料庫中加入這名使用者資料(包括SocketId)
// 回傳使用者資訊
const payLoad = {
id,
name,
avatar,
account
}
io.sockets.emit('receiveOnline', payLoad)
})
client端接收:
sockets: {
receiveOnline(data) {
// 接收到事件就 push 到 onlineUsers 陣列中
// 訊息欄位也push進去一個上線資料
}
}
通道 - 下線事件:
sendOffline(發) >> sendOffline(收)receiveOffline(發) >> receiveOffline(收)
client端發出通道請求:
// logout 時觸發
this.$socket.emit('sendOffline', {
userId: 1
})
server端回監聽並覆請求:
socket.on('sendOffline', (data) => {
// 從線上使用者資料庫中根據userId刪除這名使用者資
// 直接發回送給所有人
const user = {
id,
name,
avatar
}
io.sockets.emit('receiveOffline', user)
})
client端接收:
sockets: {
receiveOffline(data) {
// 接收到事件就從 onlineUsers 找到對應id並抽掉
// 訊息欄位也push進去一個下線資料
}
}
頁面:ChatPrivate.vue
路由:/chat/private
通道 - 私人傳訊:
sendPrivate(發) >> sendPrivate(收)receivePrivate(發) >> receivePrivate(收)
client端發出通道請求:
// vue beforeDestroy時觸發
this.$socket.emit('sendPrivate', {
sendUserId: 1, // 自己的id(這邊也可透過socket.id去找到傳訊使用者資料)
receiveUserId: 2 // 對方id
text: '' // 訊息內容
})
server端回監聽並覆請求:
socket.on('sendPrivate', (data) => {
// 到線上使用者資料裡面確認對方是否在線上,沒有就不讓對方傳訊息
if (對方不在線上) {
socket.emit('error', '對方不在線上')
// 前端再從error監聽到事件觸發,alert('對方不在線上')
return
}
// 到資料庫裡根據 sendUserId與receiveUserId找到對應的資料
const payLoad = {
sendUser: {
userId, userName, userAvatar, socketId, createdAt
},
text: ''
}
// 發送給 socket.id 對應的使用者
io.to(socketId).emit('receivePrivate',data)
})
client端接收:
sockets: {
receivePrivate(data) {
// 訊息欄位push進去一筆訊息
}
}
頁面:Notification.vue