【发布时间】:2019-12-20 03:51:19
【问题描述】:
说明
项目结构:
- 一个基于 Vue 的 FE 项目。
- 后端的 Rails( api-only ) 项目。 ruby263@rails517
要求:
- FE打开一个websocket链接,使用参数
{ weigh_device_id : 1}订阅。 - BE 确认订阅。
- 通过 weight_device_id 查找设备。
- 当客户端调用“WeighDevice#sync_reading”时,BE立即发送设备读数。
- 当设备读数更新时,BE主动发送新的设备读数。
“称重设备”模型
weighDevice : {
id: integer,
reading: integer
}
我做了什么
导轨
# config/routes.rb
Rails.application.routes.draw do
mount ActionCable.server => '/ws'
end
# app/channels/application_cable/connection.rb
# I don't need Authorization
module ApplicationCable
class Connection < ActionCable::Connection::Base
def connect
end
end
end
# app/channels/application_cable/channel.rb
# I don't need Authorization
module ApplicationCable
class Channel < ActionCable::Channel::Base
end
end
# app/channels/weigh_device_channel.rb
class WeighDeviceChannel < ApplicationCable::Channel
def subscribed
# next line code is for the requirement 4th .
stream_from "WeighDeviceChannel"
# next line code is for the requirement 5th .
# that's mean I want to broadcast message out of this Channel class .
# but I don't know how to do that ... so , here is a trial ...
# I'm not finding device by id ,directly using the last .
stream_for WeighDevice.last
end
def unsubscribed
end
def sync_reading(args)
# this solve the requirement 4th .
# the client received the reading immediately .
ActionCable.server.broadcast('WeighDeviceChannel', {reading: 0})
end
end
# I didn't write 'after_commit' in WeighDeviceModel .
# I just make a trial in rails console .
# rails c
ActionCable.server.broadcast_to('WeighDeviceChannel', {reading: 0});
# nothing happened, client didn't receive anything but 'ping' .
# then I tried this
ActionCable.server.broadcast_to(WeighDeviceChannel.last, {reading: 0});
# nothing happened either, client didn't receive anything but 'ping' .
Javascript
// Create WebSocket connection.
const socket = new WebSocket('ws://localhost:3000/ws/');
// Connection opened
socket.addEventListener('open', function (event) {
socket.send(JSON.stringify({
"command":"subscribe",
"identifier": JSON.stringify({channel: 'WeighDeviceChannel'});
});
let sent = false;
// Listen for messages
socket.addEventListener('message', function (event) {
const data = JSON.parse(event.data);
console.log(data); // checking what the server say here .
if(data.type = 'confirm_subscription' && !sent){
socket.send(JSON.stringify({
"command":"message",
"identifier": JSON.stringify({channel: 'WeighDeviceChannel'}),
"data":JSON.stringify({message:'hello-server',
action:'sync_reading'})
}));
sent = true;
}
});
所以,这里有问题。
-
broadcast_to和broadcast有什么区别? -
broadcast_to和broadcast接受不同的参数并在不同的字段中可用。也就是说,我只能在WeighDeviceChannel#action中使用broadcast,但不能在其中使用。我只能使用broadcast_toout ofWeighDeviceChannel#action但不能在其中使用。 - 为什么我在客户端收不到任何东西?我的演示有什么问题?
【问题讨论】:
-
什么是 FE 或 BE?
-
对不起,我没有描述清楚。这是前端和后端。
标签: ruby-on-rails websocket actioncable