我正在尝试使用Action Cable创建一个简单的类似聊天的应用程序(计划扑克应用程序).我对术语,文件层次结构以及回调的工作方式感到有些困惑.
这是创建用户会话的操作:
class SessionsController < ApplicationController
def create
cookies.signed[:username] = params[:session][:username]
redirect_to votes_path
end
end
Run Code Online (Sandbox Code Playgroud)
然后,用户可以发布应该向所有人广播的投票:
class VotesController < ApplicationController
def create
ActionCable.server.broadcast 'poker',
vote: params[:vote][:body],
username: cookies.signed[:username]
head :ok
end
end
Run Code Online (Sandbox Code Playgroud)
到目前为止,一切都很清楚,并且工作正常.问题是 - 如何显示已连接用户的数量?当用户(消费者?)连接时,JS中是否会触发回调?我想要的是当我在隐身模式下在3个不同浏览器中打开3个标签时,我想显示"3".当新用户连接时,我希望该数字递增.如果任何用户断开连接,则该号码应减少.
我的PokerChannel:
class PokerChannel < ApplicationCable::Channel
def subscribed
stream_from 'poker'
end
end
Run Code Online (Sandbox Code Playgroud)
app/assets/javascripts/poker.coffee:
App.poker = App.cable.subscriptions.create 'PokerChannel',
received: (data) ->
$('#votes').append @renderMessage(data)
renderMessage: (data) ->
"<p><b>[#{data.username}]:</b> #{data.vote}</p>"
Run Code Online (Sandbox Code Playgroud) 我正在将Jelastic用于我的开发环境(尚未投入生产).我的应用程序与Unicorn一起运行,但我发现带有ActionCable的websockets并将其集成到我的应用程序中.
一切都在本地工作正常,但在部署到我的Jelastic环境(使用默认的NGINX/Unicorn配置)时,我在我的javascript控制台中收到此消息,我在访问日志中看不到任何内容
WebSocket connection to 'ws://dev.myapp.com:8080/' failed: WebSocket is closed before the connection is established.
Run Code Online (Sandbox Code Playgroud)
我曾经在我的本地环境中通过在配置文件中添加所需的ActionCable.server.config.allowed_request_origins来解决它.所以我仔细检查了我的开发配置,这没关系.
这就是为什么我想知道NGINX配置是否有特定的东西,除了在ActionCable git页面上解释的内容
bundle exec puma -p 28080 cable/config.ru
Run Code Online (Sandbox Code Playgroud)
对于我的应用程序,我在这里输入链接描述,但没有提及任何有关NGINX配置的内容
我知道带有ActionCable的websocket很新,但我希望有人能够在这方面给我一个带头
非常感谢
我正在尝试创建一个暴露ActionCable频道的gem,但我无法让它工作.
这是我的宝石
# lib/my_channel.rb
class MyChannel < ActionCable::Channel::Base
def wait(data)
# logic ...
end
end
# lib/engine.rb
module MyApp
class Engine < ::Rails::Engine
isolate_namespace MyApp
end
end
Run Code Online (Sandbox Code Playgroud)
然后我将gem添加到我的主应用程序中Gemfile,运行bundle install,启动控制台并运行MyChannel.哪个不产生和错误,意味着通道被正确包含.
然后我将其添加到我的主应用程序中
// application.js
var socket = "ws://localhost:3000/cable";
var cable = ActionCable.createConsumer(socket);
cable.subscriptions.create({ "channel": "MyChannel" }, {
received: function(){
// ...
}
});
Run Code Online (Sandbox Code Playgroud)
但是我收到了这个错误
Subscription class not found ({"command"=>"subscribe", "identifier"=>"{\"channel\":\"MyChannel\"}"})
Run Code Online (Sandbox Code Playgroud)
我错过了什么?
我想知道测试ActionCable频道.
假设我有以下聊天频道:
class ChatChannel < ApplicationCable::Channel
def subscribed
current_user.increment!(:num_of_chats)
stream_from "chat_#{params[:chat_id]}"
stream_from "chat_stats_#{params[:chat_id]}"
end
end
Run Code Online (Sandbox Code Playgroud)
该subscribed方法更新数据库并定义了两个要在整个频道上广播的流,但细节不是很重要,因为我的问题更为通用:
RSpec在测试类似的交互操作(如控制器操作)时提供了许多辅助方法和各种实用程序,但我可以找到有关RSpec和ActionCable的任何内容.
为什么我无法current_user在我的频道内检索或我应该如何检索current_user?
我该用什么?
尝试current_user进入我的ActionCable频道,如rubydoc.info中所述
代码看起来像
class MessageChannel < ApplicationCable::Channel
identified_by :current_user
def subscribed
stream_from 'message_' + find_current_user_privileges
end
def unsubscribed
# Any cleanup needed when channel is unsubscribed
end
protected
def find_current_user_privileges
if current_user.has_role? :admin
'admin'
else
'user_' + current_user.id
end
end
end
Run Code Online (Sandbox Code Playgroud)
运行它,我得到这个错误:
[NoMethodError - undefined method `identified_by' for MessageChannel:Class]
Run Code Online (Sandbox Code Playgroud)
如果我删除identified_by :current_user,我得到
[NameError - undefined local variable or method …Run Code Online (Sandbox Code Playgroud) 在development环境中,rails logger记录所有有时令人讨厌的ActionCable事件(对于我的项目,它不时地传输消息并且日志尾部像野马一样运行).什么是从ActionCable中抑制所有事件日志的有效方法?另外,如何抑制某些特定的ActionCable事件?
这里的描述似乎暗示stream_for仅在传递记录时使用,但整体而言文档相当模糊.任何人都可以解释之间的差异stream_from,stream_for以及为什么你会使用其中一个?
我们已经在Heroku上使用ActionCable已经有一段时间了,总体而言它运行良好.但是,我们H15 Idle Connection每天都会多次看到错误.他们总是有path=/cable很长一段service时间,所以这种联系在一段时间内绝对是健康和健康的.
Dec 2016 08:32:22.057 heroku router - - at=error code=H15 desc="Idle connection"
method=GET path="/cable" host=<our host> dyno=web.2 connect=1ms service=928755ms status=503
Run Code Online (Sandbox Code Playgroud)
我相信我们的设置非常标准,并且紧跟ActionCable的Rails文档:
module ApplicationCable
class Connection < ActionCable::Connection::Base
identified_by :current_user
def connect
self.current_user = find_verified_user
end
protected
def find_verified_user
if current_user = User.find_by(id: cookies.signed[:user_id])
current_user
else
# reject_unauthorized_connection
end
end
end
end
Run Code Online (Sandbox Code Playgroud)
我们有三个这样简单的渠道:
class ActivitiesChannel < ApplicationCable::Channel
def subscribed
stream_from "activities_#{current_user.id}" if current_user
end
end
Run Code Online (Sandbox Code Playgroud)
编辑添加 - Javascript代码:
app/assets/javascripts/channels/setup.js:
//= require cable …Run Code Online (Sandbox Code Playgroud) 我在我的应用程序中有两个设计身份验证模型,并希望在它们之间创建聊天.任何人都知道如何为用户编写连接.以下是我所拥有的.我想检查是否可以有两个连接根据各自的登录拒绝不同用户的连接.任何帮助表示赞赏.
module ApplicationCable
class Connection < ActionCable::Connection::Base
identified_by :current_user
identified_by :current_supplier
def connect
self.current_user = find_verified_user
self.current_supplier = find_verified_supplier
end
private
def find_verified_user
if current_user = env['warden'].user('user')
current_user
end
end
def find_verified_supplier
if current_supplier = env['warden'].user('supplier')
current_supplier
else
reject_unauthorized_connection
end
end
end
end
Run Code Online (Sandbox Code Playgroud) 我正在使用带有ActionCable的Ruby on Rails 5.1.我想使用minitest测试一个特定的方法,并模拟"ActionCable.server.broadcast"调用以验证我发送的数据是否正确
module MyModule
class Scanner
def trasmit
...
ActionCable.server.broadcast "my_channel", data: msg_data
Run Code Online (Sandbox Code Playgroud)
但我不知道在我的minitest类中我如何验证ActionCable如何广播正确的消息数据.