基礎邏輯:

client發 >> server收,資料處理,server發 >> client收

*不管名稱為何,只要 client發送渠道名稱 = server接收渠道名稱 or server發送渠道名稱 = client接收渠道名稱,就能夠做到一發一收!!!!!!!!!!!(詳情看夏方程式碼)

公開聊天室 - Public Chat

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/6d8e9ecb-d11b-466c-a3ff-4dfe5145acbd/ExportedContentImage_00_(4).png

頁面: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進去一個下線資料
		}
	}

私人聊天室 - Private Chat

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/15b4562d-cc1e-4002-9bd6-c5be1f4d8908/ExportedContentImage_01_(3).png

頁面: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

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/95491d5f-6ceb-411d-bc40-694827f80a88/ExportedContentImage_04_(2).png

頁面:Notification.vue