# [實作篇]Signaling Server - Socket.io Events
# 目標
本章將使用socket來完成 WebRTC 中基本的Signaling交換,包含offer
,answer
,icecandidate
,
使用情境:
- Client A / B 會進入相同房間(如聊天室)
- Client A / B 會發起視訊聊天的請求
- Client A / B 會交換彼此SDP offer/answer
- Client A / B 會交換彼此ICE
- Client A / B 某一方離開房間
# 實作
附上完整程式碼 - github
依照需求擬定了以下幾個Events。
const onConnection = (socket) => {
// Listening for joining a room (joinRoom event)
socket.on("joinRoom", /** 加入房間 */);
socket.on("disconnect", /** 離線 */);
// for peer to peer communicate
socket.on("offer", /** SDP offer */);
socket.on("answer", /** SDP answer */);
socket.on("icecandidate", /** ICE */);
};
接下來將邏輯的部份拆分封裝到同一包檔案中( event.js )。
資料緩存及其結構
// ./event.js // 緩存使用者資訊 // 資料結構:使用者.房間名稱(目前先寫死一間) const users = { general: {}, };
joinRoom 加入房間
// ./event.js const joinRoom = (socket) => ({ username, room }) => { socket.join(room, () => { // push user for the suitable room users[room][socket.client.id] = { username: username, id: socket.client.id } // Notify all the users in the same room socket.broadcast.in(room).emit('newUser', users[room]); }); }
leaveRoom 離線
// ./event.js const leaveRoom = (socket) => ({ room, username }) => { socket.leave(room, () => { delete users[room][socket.client.id] // Notify all the users in the same room socket.broadcast.in(room).emit('userLeave', users[room]); }) }
SDP Offer
// ./event.js const offer = (socket) => ({room, offer}) => { console.log('switch offer') // Notify all the users in the same room socket.broadcast.in(room).emit('offer', offer); }
SDP Answer
// ./event.js const answer = (socket) => ({room, answer}) => { console.log('switch answer') // Notify all the users in the same room socket.broadcast.in(room).emit('answer', answer); }
ICE
// ./event.js const icecandidate = (socket) => ({room, candidate}) => { console.log('switch icecandidate') // Notify all the users in the same room socket.broadcast.in(room).emit('icecandidate', candidate); }
最後
完成所有邏輯處理後,改寫一下原本的函式。
const onConnection = (socket) => {
// Listening for joining a room (joinRoom event)
socket.on("joinRoom", events.joinRoom(socket));
socket.on("disconnect", () =>
events.leaveRoom(socket)({ room: "general" })
);
// for peer to peer communicate
socket.on("offer", (offer) => events.offer(socket)({room: "general", offer}));
socket.on("answer", (answer) => events.answer(socket)({room: "general", answer}));
socket.on("icecandidate", (candidate) => events.icecandidate(socket)({room: "general", candidate}));
};
# 總結
實作Signaling Server 基本需要的幾個功能
- 驗證/保存使用者身份(這邊是實作簡單的加入同間房間而已)
- SDP offer/answer
- ICE
接下來會將之前靜態單頁的概念實作,改為用Signaling server作為中介層,讓實作起來的感覺更接近實務應用~