How to Build Real‑Time Chat in WeChat Mini‑Programs Using WebSocket

This guide explains how to implement live‑room features such as comments, joining, leaving, likes, follows, and product updates in a WeChat mini‑program by using WebSocket for full‑duplex communication, covering the handshake process, API usage, message handling logic, and heartbeat‑based reconnection strategies.

Open Source Tech Hub
Open Source Tech Hub
Open Source Tech Hub
How to Build Real‑Time Chat in WeChat Mini‑Programs Using WebSocket

Introduction

WebSocket provides full‑duplex, low‑latency communication over a single TCP connection. In WeChat Mini‑Programs it is commonly used for real‑time features such as live‑room comments, join/leave notifications, likes, follows, and product on/off‑shelf events.

What is WebSocket?

WebSocket is a protocol defined by RFC 6455. After an initial HTTP handshake the client and server keep a persistent connection, allowing either side to push data at any time without additional request/response cycles.

Communication Flow

WebSocket communication flow
WebSocket communication flow

Typical WebSocket Handshake

Client request

GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Origin: http://example.com
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13

Server response

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
Sec-WebSocket-Protocol: chat

Field explanation

Connection: Upgrade

signals a protocol upgrade request. Upgrade: websocket specifies the desired protocol. Sec-WebSocket-Key is a random Base64 string generated by the client. The server appends the GUID 258EAFA5-E914-47DA-95CA-C5AB0DC85B11, computes a SHA‑1 hash, Base64‑encodes the result, and returns it in Sec-WebSocket-Accept. Sec-WebSocket-Version: 13 is the only version required by the final RFC. Origin (optional) indicates the page that initiated the connection, similar to the HTTP Referer header but without path information.

WebSocket API in WeChat Mini‑Programs

wx.connectSocket

– creates a WebSocket connection. socket.onOpen – fires when the connection is established. socket.onClose – fires when the connection is closed. socket.onError – fires on error events. socket.onMessage – receives messages from the server (core for data handling). socket.send – sends data to the server (core for transmitting data).

Basic usage example

var socket = null;
var socketOpen = false;
var wsBasePath = "ws://your-server-address/";

function startWebSocket() {
  socket = wx.connectSocket({
    url: wsBasePath,
    success: res => console.log('Connection succeeded:', res),
    fail: err => {
      console.log('Connection error:', err);
      wx.showToast({title: 'Network error'});
    }
  });
  bindSocketEvents();
}

function bindSocketEvents() {
  socket.onOpen(res => {
    socketOpen = true;
    console.log('WebSocket opened', res);
  });
  socket.onClose(err => {
    console.log('WebSocket closed', err);
    socketOpen = false;
  });
  socket.onError(err => {
    console.log('WebSocket error', err);
    socketOpen = false;
  });
  socket.onMessage(msg => {
    var data = JSON.parse(msg.data);
    console.log('Received message', data);
    // Process different msg_type values here
  });
}

function sendSocketMessage(msg) {
  if (socketOpen) {
    console.log('Sending message', JSON.stringify(msg));
    socket.send({
      data: JSON.stringify(msg),
      success: res => console.log('Sent', res)
    });
  }
}

function closeWebSocket(reason) {
  if (socketOpen) {
    socket.close({
      code: "1000",
      reason: reason,
      success: () => console.log('WebSocket closed')
    });
  }
}

Message handling logic

The onMessage callback parses the incoming JSON, checks the msg_type field and updates UI or internal state accordingly. Outgoing messages must also contain a type (or msg_type) defined by the backend so the server can route the request.

Typical msg_type values include: init – initial data after login. join – user joins the live room. message – a chat comment. subscribe – a follow event. leave – user leaves the room. buy – product purchase or shelf change.

Heartbeat detection and automatic reconnection

In production a Mini‑Program must keep the connection alive, detect network changes, and reconnect when the socket is closed unexpectedly. The following class encapsulates these responsibilities.

export default class WebSocketManager {
  constructor({ heartCheck = true, isReconnection = true } = {}) {
    this._isLogin = false;          // whether the socket is logged in
    this._netWork = true;           // current network status
    this._isClosed = false;         // whether the user manually closed the socket
    this._timeout = 3000;           // heartbeat interval (ms)
    this._timeoutObj = null;         // timer reference
    this._connectNum = 0;           // reconnection attempt counter
    this._heartCheck = heartCheck;   // enable/disable heartbeat
    this._isReconnection = isReconnection; // enable/disable auto‑reconnect
    this._onSocketOpened();
  }

  // ---------- heartbeat ----------
  _reset() {
    clearTimeout(this._timeoutObj);
    return this;
  }

  _startHeartbeat() {
    const that = this;
    this._timeoutObj = setInterval(() => {
      wx.sendSocketMessage({
        data: JSON.stringify({ msg_type: 'ping' }),
        success(res) { console.log('Heartbeat sent', res); },
        fail(err) { console.log('Heartbeat failed', err); that._reset(); }
      });
    }, this._timeout);
  }

  // ---------- socket event bindings ----------
  _onSocketOpened() {
    wx.onSocketOpen(res => {
      console.log('WebSocket opened');
      this._isLogin = true;
      if (this._heartCheck) this._reset()._startHeartbeat();
      // send an optional login payload after the connection is ready
      wx.sendSocketMessage({ data: JSON.stringify({ key: 'value' }) });
      this._netWork = true;
    });
  }

  onSocketClosed(options) {
    wx.onSocketClose(err => {
      console.log('WebSocket closed:', JSON.stringify(err));
      if (this._heartCheck) this._reset();
      this._isLogin = false;
      if (!this._isClosed && this._isReconnection) this._reConnect(options);
    });
  }

  onNetworkChange(options) {
    wx.onNetworkStatusChange(res => {
      console.log('Network status:', res.isConnected);
      if (!this._netWork && this._isReconnection) this._reConnect(options);
    });
  }

  onReceivedMsg(callback) {
    wx.onSocketMessage(msg => {
      if (typeof callback === 'function') {
        callback(msg);
      } else {
        console.log('Callback must be a function');
      }
    });
  }

  // ---------- connection management ----------
  initWebSocket(options) {
    if (this._isLogin) {
      console.log('Already logged in');
      return;
    }
    wx.getNetworkType({
      success: result => {
        if (result.networkType !== 'none') {
          wx.connectSocket({
            url: options.url,
            success: res => typeof options.success === 'function' && options.success(res),
            fail: err => typeof options.fail === 'function' && options.fail(err)
          });
        } else {
          console.log('Network disconnected');
          this._netWork = false;
          wx.showModal({ title: 'Network error', content: 'Please reconnect', showCancel: false });
        }
      }
    });
  }

  sendWebSocketMsg(options) {
    wx.sendSocketMessage({
      data: options.data,
      success: res => typeof options.success === 'function' && options.success(res),
      fail: err => typeof options.fail === 'function' && options.fail(err)
    });
  }

  // ---------- reconnection strategy (exponential back‑off) ----------
  _reConnect(options) {
    let delay;
    if (this._connectNum < 20) {
      delay = 3000;          // first 20 attempts: 3 s interval
    } else if (this._connectNum < 50) {
      delay = 10000;         // next 30 attempts: 10 s interval
    } else {
      delay = 450000;        // thereafter: 7.5 min interval
    }
    setTimeout(() => this.initWebSocket(options), delay);
    this._connectNum += 1;
  }

  closeWebSocket() {
    wx.closeSocket();
    this._isClosed = true;
  }
}

This class provides:

Automatic heartbeat transmission to keep the TCP connection alive.

Detection of socket closure and network status changes.

Exponential back‑off reconnection logic to avoid hammering the server.

Simple wrappers for sending and receiving messages.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaScriptWeChat Mini ProgramWebSocketreal-time communicationreconnection
Open Source Tech Hub
Written by

Open Source Tech Hub

Sharing cutting-edge internet technologies and practical AI resources.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.