如何使用irealtime.js實現一個基於websocket的同步畫板

paul_xiao發表於2021-02-23

同步畫板演示

同時開啟2個tab,分別在畫布上寫下任意內容,觀察演示結果,同時可設定畫筆顏色及線條寬度。演示地址

初始化畫布

 <canvas id="drawBoard" width="700" height="400"></canvas>
   this.canvas = document.getElementById("drawBoard");
   this.ctx = this.canvas.getContext("2d");
   this.stage_info = this.canvas.getBoundingClientRect(); //初始化舞臺資訊
   this.path = { //初始化路徑
      beginX: 0,
      beginY: 0,
      endX: 0,
      endY: 0,
    };
   this.ctx.lineWidth = this.size;//初始化線條寬度

載入irealtime.js

irealtime.js 是一個第三方websocket實時訊息推送服務jssdk,可用於快速搭建安全可靠高併發的web實時通訊體系,同時支援多語言開發且相容絕大多數主流瀏覽器, 瞭解更多

  1. 引入irealtime.js
npm i irealtime --save
  1. 初始化irealtime
import IRealTime from "irealtime";

this.irealtime = new IRealTime({
  host: "hk.irealtime.cn",
  appkey: "your appkey", //如何獲取appkey: https://irealtime.cn/docs/get_account_and_appkey.html
  onConnected: function () {
    console.log("連線成功...");
  },
  onDisconnected: function () {
    console.log("連線斷開...");
  },
  onConnectFailed: function (error) {
    console.log("連線失敗...", error);
  },
});

  1. 訂閱訊息
  this.irealtime.subscribe({
      channels: ["mychannel"],
      onMessage: (data) => {
        this.syncPath(data.message); //通過irealtime將繪畫內容同步到其他客戶端
      },
      onSuccess: function () {},
      onFailed: function () {},
    });

  1. 釋出訊息
    publish(msg) {
      this.irealtime.publish({
        channel: "mychannel",
        message: msg,
        onSuccess: function (data) {
          console.log("success:", data);
        },
        onFailed: function (error) {
          console.log("failed:", error);
        },
      });
    },

開始繪畫

  1. 繫結滑鼠事件
  draw() {
      let that = this;
      this.canvas.onmousedown = (e) => {
        that.ctx.beginPath();
        that.path.beginX = e.pageX - that.stage_info.left;
        that.path.beginY = e.pageY - that.stage_info.top;
        that.ctx.moveTo(that.path.beginX, that.path.beginY);
        that.isDraw = true;//isDraw 是否開始繪畫
        this.publish(  //傳送mousedown訊息給其他客戶端
          JSON.stringify({
            type: "mousedown",
            path: this.path,
          })
        );
      };
      this.canvas.onmousemove = (e) => {
        if (that.isDraw) {
          that.drawing(e); //按下並移動滑鼠開始繪畫
        }
      };
      this.canvas.onmouseup = () => {
        that.isDraw = false;
        this.publish(   //傳送stop訊息給其他客戶端
          JSON.stringify({
            type: "stop",
            path: this.path,
          })
        );
      };
    },

  1. 繪畫動作
    drawing(e) {
      this.path.endX = e.pageX - this.stage_info.left;
      this.path.endY = e.pageY - this.stage_info.top;
      this.ctx.lineTo(this.path.endX, this.path.endY);
      this.ctx.stroke();
      let data = {
        type: "draw",
        size: this.size,
        current: this.current,
        path: this.path,
      };
      this.publish(JSON.stringify(data));//將當前繪畫路徑、線條寬度、當前顏色等資訊傳送給其他客戶端
    },

  1. 同步繪畫資訊

通過不同型別的訊息,判斷客戶端需要做的操作

  syncPath(data) {
      const { type, size, current, path } = JSON.parse(data);
      if (type === "changeColor") { //改變顏色
        this.current = current;
        this.ctx.strokeStyle = this.palette[this.current];
        return;
      }
      if (type === "changeSize") { //改變線條寬度
        this.size = size;
        this.ctx.lineWidth = this.size;
        return;
      }

      if (type == "clear") {  //清空畫布
        this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
        return;
      }
      if (this.path.beginX != path.beginX) { //防止重複
        if (type === "mousedown") {
          this.ctx.beginPath();

          this.ctx.moveTo(path.beginX, path.beginY);
          this.isDraw = 1;
        } else if (type === "draw" && this.isDraw === 1) {
          this.ctx.lineTo(path.endX, path.endY);
          this.ctx.stroke();
        }
      }
      if (type === "stop") {//停止繪畫
        this.isDraw = 0;
      }
    },

檢視原始碼

總結

本文通過使用irealtime.js的兩個簡單api(subscribe|publish)便實現了基於websocket的訊息釋出及訂閱,開發者無需過多關注websocket服務端操作,可直接使用irealtime api開發基於websocket的應用,如需瞭解更多內容,請直接訪問https://irealtime.cn/

相關文章