[我试图在ActionCable的帮助下模拟语法拼写检查,但是我有点挣扎着去理解如何
我阅读了很多文章,包括官方文档,但我感到困惑。所以,我要做的第一件事是在config/application.rb
中添加以下内容:
# Mount ActionCable.
config.action_cable.mount_path = '/websocket'
我还设置了身份验证:
module ApplicationCable
class Connection < ActionCable::Connection::Base
identified_by :current_user
def connect
self.current_user = find_verified_user
end
private
def find_verified_user
current_user = User.find_by_api_key(token)
if current_user
current_user
else
reject_unauthorized_connection
end
end
def token
# TODO: verify if this is really safe.
request.headers[:AUTHORIZATION].split('=').last
end
end
end
我不使用device
,并且我的身份验证基于令牌。每个用户都有一个固定的API令牌,就是这样。
希望认证是正确的,如果这是不正确的话,如果有经验的人可以指出我,我将不胜感激。
现在,我创建了一个名为spell_checking_channel
的频道:
class SpellCheckingChannel < ApplicationCable::Channel
def subscribed
stream_from 'spell_checking_channel_' << current_user.id
end
def unsubscribed
# Any cleanup needed when channel is unsubscribed
end
end
一旦从前端接收到数据,我想调用SpellChecker.call('text')
并将结果广播回去。我知道,我在此方面寻求帮助是荒谬的,但我确实没有找到任何示例。另外,我应该对unsubscribed
方法执行任何操作吗?
const my_token = '...';
const cable = ActionCable.createConsumer(`/websocket?token=${my_token}`);
它将在连接的request.params[:token]
中。在您的js中将数据发送到频道:
const channel = cable.subscriptions.create({ channel: "SpellCheckingChannel" }, { received(data) { // handle data from channel in some way console.log("received from rails:", data); } }); channel.send({ some_data_to_rails: "goes_here" })
在后端:
class SpellCheckingChannel < ApplicationCable::Channel def subscribed # here we instruct ActionCable to send messages from following topic stream_from "spell_checking_channel_#{current_user.id}" # there may be multiple subscriptions in one channel: stream_from "spell_checking_channel_common" end def receive(data) # channel.send(data) ends up here ActionCable.server.broadcast("spell_checking_channel_#{current_user.id}", { this_goes_back: "to js" }) if data[:foo] == "bar" ActionCable.server.broadcast("spell_checking_channel_common", { hey_listen_all: "lala" }) end end end
主要技巧是,您可以在应用程序中的任何地方使用ActionCable.server.broadcast
,不仅可以在通道中使用-例如,在通道中,您可以排队后台作业,然后将其结果发送到通道中