iT邦幫忙

2021 iThome 鐵人賽

DAY 11
0
Modern Web

摸索 WebSocket,遠望 WebRTC系列 第 11

Day10:Emit Direct Message II(Render 私人訊息到 HTML)

全文同步於個人 Docusaurus Blog

繼承前一章的內容,現在需要將 server-side 接收到的訊息,除了轉回到 client-side,同時也要做頁面 render 的動作。

Page & Style

先將 HTML 和 CSS 進行部分調整,並添加簡單樣式,方便待會直接套用在動態生成的內容上。

  <body>
    <main class="wrapper">
      // ...
      <section class="chat-box display-none">
        <p class="username-text">
          登入的使用者:<span class="username-label"></span>
        </p>
      </section>
    </main>
  </body>
.username-text {
  position: absolute;
  top: 20px;
  left: 40px;
  font-size: 36px;
}

.message-left {
  display: inline-block;
  background: white;
  border-radius: 8px 8px 8px 0px;
  border: 1px solid #d5deeb;
  color: black;
  margin: 5px;
  padding: 8px;
}

.message-right {
  float: right;
  background: linear-gradient(168.68deg, #0052c9 1.12%, #0a91db 100%);
  border-radius: 8px 8px 0px 8px;
  color: white;
  margin: 5px;
  padding: 8px;
}

Server

當玩家 A 對玩家 B 發送私人訊息時,server-side 先檢查接收訊息的一方是否還在聊天頁面中,並建立一組 socket 發給中介層。

// server.js
socket.on('direct-message', (data) => {
  const { receiverSocketId } = data;
  const hasConnectPeer = connectPeers.find(
    (peer) => peer.socketId === receiverSocketId
  );

  if (hasConnectPeer) {
    const authorData = {
      ...data,
      isAuthor: true,
    };
    socket.emit('direct-message', authorData);
    io.to(receiverSocketId).emit('direct-message', data);
  }
});

中介層監聽收到資料後,轉給 ui 的函式 appendDirectChatMessage() 使用。

// handler.js
socket.on('direct-message', (data) => {
  ui.appendDirectChatMessage(data);
});

Client

在 ui.js 使用資料前,仍要先準備好動態 render 的 HTML。除了傳入文字訊息內容,同時也檢查目前頁面 render 的部分,屬於訊息發送者還是接收者,再根據狀態決定樣式。

// element.js
const getDirectChatMessage = (data) => {
  const { textContent, alighRight } = data;
  const messageContent = document.createElement('div');
  const messageClass = alighRight ? 'message-right' : 'message-left';
  messageContent.innerHTML = `
    <p class="${messageClass}">${textContent}
  `;
  return messageContent;
};

ui.js 接收到中介層的資料後進行解構,根據狀態決定抓取接收者或是發送者的 ID。

// ui.js
const appendDirectChatMessage = (messageData) => {
  const { authorSocketId, author, messageContent, receiverSocketId, isAuthor } =
    messageData;
  const messageWrapper = isAuthor
    ? document.getElementById(`${receiverSocketId}-message`)
    : document.getElementById(`${authorSocketId}-message`);

  if (messageWrapper) {
    const data = {
      author,
      textContent: messageContent,
      alighRight: isAuthor ? true : false,
    };
    const message = element.getDirectChatMessage(data);
    messageWrapper.appendChild(message);
  }
};

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

direct message II


上一篇
Day09:Emit Direct Message I(發送個人訊息到 server 端)
下一篇
Day11:Disconnect Chat(關閉連線頻道)
系列文
摸索 WebSocket,遠望 WebRTC30

尚未有邦友留言

立即登入留言