微信小程序結(jié)合actioncable實(shí)現(xiàn)通信

參考資料
actioncable
微信小程序
在做微信小程序開(kāi)發(fā)的時(shí)候需要用到websocket通信,由于小程序沒(méi)有對(duì)actioncable.js的封裝,因此需要根據(jù)小程序的websocket接口文檔進(jìn)行傳遞參數(shù)的處理。
首先看一下使用actioncable.js模塊時(shí)的網(wǎng)絡(luò)數(shù)據(jù)傳輸情況

訂閱頻道

訂閱之后返回信息
發(fā)送消息

通過(guò)以上三張截圖可以很明確的看到actioncable.js所做的事情,把rails服務(wù)器端需要的數(shù)據(jù)進(jìn)行封裝,按照固定的格式進(jìn)行數(shù)據(jù)傳輸。
so!為了在小程序中實(shí)現(xiàn)同樣的功能,只需要按照這個(gè)格式對(duì)傳遞的參數(shù)進(jìn)行相應(yīng)的封裝即可。

創(chuàng)建服務(wù)器端代碼

rails g channel qagame # 創(chuàng)建channel

為了讓小程序可以訪問(wèn)到服務(wù)器端的數(shù)據(jù),需要修改actioncable的配置
config/application.rb

# 添加action_cable配置,關(guān)閉跨域檢測(cè)
config.action_cable.disable_request_forgery_protection = true
class QagameChannel < ApplicationCable::Channel
  def subscribed
    stream_from "qagame_channel"
  end

  def unsubscribed
    # Any cleanup needed when channel is unsubscribed
  end

  def join_challenge(data)
    p "獲取客戶(hù)端數(shù)據(jù):#{data}"
    ActionCable.server.broadcast("qagame_channel", "登錄成功") # 返回?cái)?shù)據(jù)到客戶(hù)端
  end
end

客戶(hù)端

const app = getApp()

Page({
  ...
  onLoad: function () {
    // test websocket
    wx.connectSocket({
      url: 'ws://localhost:3000/cable',
      header: {
        'content-type': 'application/json'
      },
      method: "GET"
    });
    const id = JSON.stringify({ channel: "QagameChannel", id: '這個(gè)是訂閱參數(shù)' });
    wx.onSocketOpen(function () {
      wx.sendSocketMessage({
        data: JSON.stringify({ command: "subscribe", identifier: id}),
      })
    })
    // 延時(shí)發(fā)送命令,等待客戶(hù)端和服務(wù)器連接成功 
    setTimeout(function(){
      wx.sendSocketMessage({
        data: JSON.stringify({
          command: 'message',
          data: JSON.stringify({ 
            openid: 123,
            action: 'join_challenge'
            }),
          identifier: id
        }),
      })
    }, 5000)
    wx.onSocketMessage(function(res){
      console.log(res);
    })
    wx.onSocketClose(function(res){
      console.log("連接已關(guān)閉")
      console.log(res)
    })
    wx.onSocketError(function(err){
      console.log("打開(kāi)連接失敗")
      console.log(err)
    })
  },
  ...
})

附上自己定義的Actioncable

const formatTime = date => {
  const year = date.getFullYear()
  const month = date.getMonth() + 1
  const day = date.getDate()
  const hour = date.getHours()
  const minute = date.getMinutes()
  const second = date.getSeconds()

  return [year, month, day].map(formatNumber).join('/') + ' ' + [hour, minute, second].map(formatNumber).join(':')
}

const formatNumber = n => {
  n = n.toString()
  return n[1] ? n : '0' + n
}

// 
class Actioncable {
  /**
   * url ws服務(wù)器地址 http://localhost:3000/cable
   * channel  服務(wù)端channel名字如:GameChannel
   * id       可選參數(shù),
   * cb       接受返回?cái)?shù)據(jù)的回調(diào)函數(shù)
   */
  constructor(url, channel, id, cb) {
    wx.connectSocket({
      url,
      header: {
        'content-type': 'application/json'
      },
      method: "GET"
    })
    this.identifier = JSON.stringify({ channel, id });
    wx.onSocketOpen(() => {
      wx.sendSocketMessage({
        data: JSON.stringify({ command: "subscribe", identifier: this.identifier }),
      })
    })
    wx.onSocketMessage((res) => {
      console.log(res) // 服務(wù)器端返回?cái)?shù)據(jù)
      res = JSON.parse(res.data);
      if (JSON.stringify(res.identifier) == JSON.stringify(this.identifier)){
        if(res.message) {
          cb(res)
        }
      }
    })
    wx.onSocketClose(function (res) {
      console.log("連接已關(guān)閉")
      console.log(res)
    })
    wx.onSocketError(function (err) {
      console.log("打開(kāi)連接失敗")
      console.log(err)
    })
  }

  /**
   * 發(fā)送消息
   *  action  channel中定義的action名字
   *  data    傳遞到action的數(shù)據(jù)
   */
  sendMessage(action, data) {
    var info = {}
    data.action = action
    info.command = 'message'
    info.identifier = this.identifier
    info.data = JSON.stringify(data)
    wx.sendSocketMessage({
      data: JSON.stringify(info),
    })
  }
}

module.exports = {
  formatTime: formatTime,
  Actioncable
}

調(diào)用例子

const ws = new Actioncable('ws://localhost:3000/cable', 'QagameChannel', 1211, function(res){
      console.log(res);
    })
setTimeout(() => ws.sendMessage('join_challenge', { openid: 123, nick_name: 'Timer' }), 5000);

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容