iT邦幫忙

2021 iThome 鐵人賽

DAY 14
0
Modern Web

摸索 WebSocket,遠望 WebRTC系列 第 14

Day13:Send Message To Room(發送訊息到特定房間)

全文同步於個人 Docusaurus Blog

建立完成特定頻道後,再來就是在指定頻道中發出個人訊息,運作邏輯和公共頻道類似,差別僅在於,只有進入該頻道的人可以查看訊息。

Client-side 輸入訊息

同樣先從 ui 出發,檢查使用者是否在房間中輸入訊息,監聽鍵盤事件,當觸發時則傳遞訊息資料給 handler.js。

// ui.js
const createRoomChat = () => {
  // ...
  const newMessageInput = document.getElementById(messageInputID);
  newMessageInput.addEventListener('keydown', (e) => {
    const key = e.key;

    if (key === 'Enter') {
      const author = store.getUserName();
      const messageContent = e.target.value;
      const authorSocketId = store.getSocketId();

      const data = {
        author,
        messageContent,
        authorSocketId,
        roomId,
      };

      socketHandler.sendRoomMessage(data);
      newMessageInput.value = '';
    }
  });
};

handler 將取得的資料透過 emit 轉發給 server-side,同時建立 socket 連線。

// handler.js
const sendRoomMessage = (data) => {
  socket.emit('room-message', data);
};

server-side 除了監聽 connection(),將房間 ID 存入外,同時也得將它再轉發回 handler.js,方便中介層重新遞給 ui.js。

// server.js
socket.on('room-message', (data) => {
  const { roomId } = data;

  io.to(roomId).emit('room-message', data);
});
// handler.js
socket.on('room-message', (data) => {
  ui.appendRoomChatMessage(data);
});

Render

渲染的部分就和公共頻道類似,無論是抓取 DOM 和動態塞入資料都是一樣的邏輯。

// ui.js
const appendRoomChatMessage = (data) => {
  const { roomId, author, messageContent } = data;
  const roomChatMessageId = `${roomId}-message`;
  const roomMessageWrapper = document.getElementById(roomChatMessageId);

  const roomData = {
    author,
    messageText: messageContent,
  };

  const roomMessage = element.getChatMessageContent(roomData);
  roomMessageWrapper.appendChild(roomMessage);
};

export default {
  // ...
  appendRoomChatMessage,
};

send message to room


上一篇
Day12:Select Room(選擇特定房間頻道)
下一篇
Day14:插曲(小結)
系列文
摸索 WebSocket,遠望 WebRTC30

尚未有邦友留言

立即登入留言