algora-io / tv

Open source Twitch for developers
https://algora.tv
Other
1.01k stars 59 forks source link

add raw websocket handler for chat messages #55

Closed zcesur closed 3 months ago

zcesur commented 3 months ago

Example WebSocket client w/ heartbeats & reconnections

class AlgoraSocket {
  constructor(channel) {
    this.url = `wss://tv.algora.io/chat/${channel}/websocket`;
    this.scheduleHeartBeat();
  }

  connect() {
    this.hasErrored = false;
    this.socket = new WebSocket(this.url);
    let that = this;
    this.socket.onclose = () => {
      that.onClose();
    };
    this.socket.onerror = (errorEvent) => {
      that.onError(errorEvent);
    };
    this.socket.onmessage = (messageEvent) => {
      that.onMessage(messageEvent);
    };
    this.attemptReopen = true;
  }

  close() {
    this.attemptReopen = false;
    if (this.socket) this.socket.close();
    this.socket = null;
    clearTimeout(this.heartBeatId);
  }

  onClose() {
    this.maybeReopen();
  }

  onError(errorEvent) {
    this.hasErrored = true;
  }

  onMessage(messageEvent) {
    console.log("message", JSON.parse(messageEvent.data));
  }

  isSocketClosed() {
    return this.socket == null || this.socket.readyState == 3;
  }

  maybeReopen() {
    let after = this.hasErrored ? 2000 : 0;
    setTimeout(() => {
      if (this.isSocketClosed() && this.attemptReopen) this.connect();
    }, after);
  }

  scheduleHeartBeat() {
    let that = this;
    this.heartBeatId = setTimeout(function () {
      that.sendHeartBeat();
    }, 30000);
  }

  sendHeartBeat() {
    if (this.socket) {
      this.socket.send("💜");
    }
    this.scheduleHeartBeat();
  }
}

Usage

const socket = new AlgoraSocket("zaf")
socket.connect()

Message schema

export interface AlgoraMessage {
  body: string
  platform: string
  sender_handle: string
  sender_name: string
  sender_avatar_url: string
  inserted_at: string
}

Message example

{
  "body": "Lorem ipsum",
  "platform": "algora",
  "sender_handle": "zaf",
  "sender_name": "Zafer Cesur",
  "sender_avatar_url": "https://avatars.githubusercontent.com/u/17045339?v=4",
  "inserted_at": "2024-07-11T16:32:30"
}