参考资料
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);