iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 27
1
Modern Web

每日挖個坑,用坑填起耍廢聊天室!系列 第 27

二十七號坑,來做多個聊天頻道之三(socket事件篇)

今天要來處理socket的部分,下面是邀請線上人的流程
https://ithelp.ithome.com.tw/upload/images/20191012/20111962jilpO9nTEW.png

  1. A新增頻道
  2. 邀請B
  3. 通知B要被加入頻道
  4. B接受並加入頻道

原本我第一版的寫法,因為沒認真看文件(咦),所以先硬幹了一版,用資料記每個頻道有誰,然後用迴圈一個一個發訊息出去,直到我發現了join這東東,還是認份地換了一個版本Orz

socket.join('roomName', () => {
    //join會把使用者加到`roomName`,之後就可以針對roomName裡的人發送訊息
    io.to('roomName').emit('msg'); 
  });

https://ithelp.ithome.com.tw/upload/images/20191012/20111962RAyQ5qKLs4.png

  • A新增頻道
    https://ithelp.ithome.com.tw/upload/images/20191012/20111962GcDXfRDYBw.png

我把觸發事件做在這上面(vue)

addChat() {
    let newChannel = {
      channelId: this.newKey(),
      name: 'undefined',
      members: [this.loginData],
      msg: []
    }
    this.$socket.emit('newChannel', newChannel, () => {
      this.SET_CHANNEL(newChannel) // 將新頻道資料送給socket後將頻道資料也存到store去
    })
  },

socket上監聽newChannel新增聊天室(把自己加進一個新的頻道)(socket)

socket.on("newChannel", (data, callback) => {
    socket.join(data.channelId, () => {
      callback(); // 加進頻道後callback把頻道資料丟到store
    });
  });
  • 邀請B(vue)
    目前邀請人做得很陽春,直接點線上人列表,就可以把對方加進來
inviteMember(member) {
    const sendData = {
      channel: this.channels.now,
      member: member
    }
    this.$socket.emit('inviteMember', sendData, () => {
      this.INVITE_MEMBER(sendData) // callback更新A端頻道成員資料
    })
  },
  • socket通知B要被加入頻道(socket)
    socket接收到邀請通知,並通知受邀人
socket.on("inviteMember", (data, callback) => {
    // 針對邀請對象發出joinChannel事件
    io.to(data.member.socketId).emit("joinChannel", data.channel);
    callback();
  });
  • B接受並加入頻道(vue)
    我這邊沒有特別做確認加入之類的介面通知,直接被拐進去直接就接受邀請加入頻道
joinChannel(channel) {
    this.$socket.emit('acceptJoin', channel,()=>{
        // callback後更新B方的store資料
        this.SET_CHANNEL(channel)
        this.SET_NOW_CHANNE(channel)
    })
  },

socket將B加入頻道

socket.on("acceptJoin", (channel, callback) => {
    // 接受聊天室邀請
    socket.join(channel.channelId, () => {
      callback();
    });
  });

最後調整一下傳訊息的那個事件(socket)
all的時候就是在聊天大廳,收到的訊息就全世界發送,不是的話就是針對頻道的人傳訊息

socket.on("msg", function(msg) {
    if (msg.channel.channelId === "all") {
      io.emit("uploadMsg", msg);
    } else {
      io.to(msg.channel.channelId).emit("uploadMsg", msg);
    }
  });

結論就是socket就是個踢皮球的概念


上一篇
二十六號坑,來做多個聊天頻道之二(介面篇)
下一篇
二十八號坑,阻擋直接用網址進來的傢伙-asyncData&fetch
系列文
每日挖個坑,用坑填起耍廢聊天室!30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言