美文网首页
微信小程序结合actioncable实现通信

微信小程序结合actioncable实现通信

作者: 李傲娢 | 来源:发表于2018-11-05 13:06 被阅读34次

    参考资料
    actioncable
    微信小程序
    在做微信小程序开发的时候需要用到websocket通信,由于小程序没有对actioncable.js的封装,因此需要根据小程序的websocket接口文档进行传递参数的处理。
    首先看一下使用actioncable.js模块时的网络数据传输情况

    订阅频道 订阅之后返回信息 发送消息

    通过以上三张截图可以很明确的看到actioncable.js所做的事情,把rails服务器端需要的数据进行封装,按照固定的格式进行数据传输。
    so!为了在小程序中实现同样的功能,只需要按照这个格式对传递的参数进行相应的封装即可。

    创建服务器端代码

    rails g channel qagame # 创建channel
    

    为了让小程序可以访问到服务器端的数据,需要修改actioncable的配置
    config/application.rb

    # 添加action_cable配置,关闭跨域检测
    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 "获取客户端数据:#{data}"
        ActionCable.server.broadcast("qagame_channel", "登录成功") # 返回数据到客户端
      end
    end
    

    客户端

    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: '这个是订阅参数' });
        wx.onSocketOpen(function () {
          wx.sendSocketMessage({
            data: JSON.stringify({ command: "subscribe", identifier: id}),
          })
        })
        // 延时发送命令,等待客户端和服务器连接成功 
        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("连接已关闭")
          console.log(res)
        })
        wx.onSocketError(function(err){
          console.log("打开连接失败")
          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服务器地址 http://localhost:3000/cable
       * channel  服务端channel名字如:GameChannel
       * id       可选参数,
       * cb       接受返回数据的回调函数
       */
      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) // 服务器端返回数据
          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("连接已关闭")
          console.log(res)
        })
        wx.onSocketError(function (err) {
          console.log("打开连接失败")
          console.log(err)
        })
      }
    
      /**
       * 发送消息
       *  action  channel中定义的action名字
       *  data    传递到action的数据
       */
      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
    }
    
    

    调用例子

    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);
    
    

    相关文章

      网友评论

          本文标题:微信小程序结合actioncable实现通信

          本文链接:https://www.haomeiwen.com/subject/sigjxqtx.html