Action Cable在开发中起作用,但在生产中不起作用。我不知道如何调试它或如何缩小问题。在生产中,我在Debian 9系统上使用puma(3.12.0),Nginx(1.10.3),Redis(3.2.6)和Rails 5.2.2(Ruby 2.5.3p105)。除了Action Cable之外,其他一切都正常。
rails生产日志以以下行结尾:
I, [...] INFO -- : [ae5f4486-eadd-466d-a4de-fd8db3cdcfb4] Successfully upgraded to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: upgrade, HTTP_UPGRADE: websocket)
D, [...] DEBUG -- : ESC[1mESC[36mUser Load (0.8ms)ESC[0m ESC[1mESC[34mSELECT "users".* FROM "users" WHERE "users"."id" IS NULL LIMIT $1ESC[0m [["LIMIT", 1]]
E, [...] ERROR -- : An unauthorized connection attempt was rejected
E, [...] ERROR -- : Failed to upgrade to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: upgrade, HTTP_UPGRADE: websocket)
I, [...] INFO -- : Finished "/cable/" [WebSocket] for 127.0.0.1 at 2019-01-14 15:52:53 +0100
I, [...] INFO -- : Finished "/cable/" [WebSocket] for 127.0.0.1 at 2019-01-14 15:52:53 +0100
I, [...] INFO -- : [58aa5ff7-e440-4050-88b6-6e9dcdc691a0] Started GET "/cable" for 127.0.0.1 at 2019-01-14 15:55:35 +0100
I, [...] INFO -- : [58aa5ff7-e440-4050-88b6-6e9dcdc691a0] Started GET "/cable/" [WebSocket] for 127.0.0.1 at 2019-01-14 15:55:35 +0100
I, [...] INFO -- : [58aa5ff7-e440-4050-88b6-6e9dcdc691a0] Successfully upgraded to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: upgrade, HTTP_UPGRADE: websocket)
D, [...] DEBUG -- : ESC[1mESC[36mUser Load (0.8ms)ESC[0m ESC[1mESC[34mSELECT "users".* FROM "users" WHERE "users"."id" IS NULL LIMIT $1ESC[0m [["LIMIT", 1]]
E, [...] ERROR -- : An unauthorized connection attempt was rejected
E, [...] ERROR -- : Failed to upgrade to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: upgrade, HTTP_UPGRADE: websocket)
I, [...] INFO -- : Finished "/cable/" [WebSocket] for 127.0.0.1 at 2019-01-14 15:55:35 +0100
I, [...] INFO -- : Finished "/cable/" [WebSocket] for 127.0.0.1 at 2019-01-14 15:55:35 +0100
Nginx配置:
upstream my_app {
server unix:/tmp/example.sock;
}
server {
listen 443 ssl;
# ... ssl configuration
server_name xyz.example.com;
root /var/www/example/current/public;
location /assets/ {
gzip_static on;
expires max;
add_header Cache-Control public;
}
location / {
try_files $uri @ruby;
}
location @ruby {
proxy_pass http://my_app;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Ssl on; # Optional
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Forwarded-Host $host;
proxy_redirect off;
}
location /cable {
proxy_pass http://my_app;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
在production.rb
中,我有以下几行:
config.action_cable.url = 'wss://xyz.example.com/cable'
config.action_cable.disable_request_forgery_protection = true
app / channels / application_cable / connection.rb
module ApplicationCable
class Connection < ActionCable::Connection::Base
identified_by :current_user
def connect
# This is a websocket so we have no warden and no session here
# How to reuse the login made with devise?
# http://www.rubytutorial.io/actioncable-devise-authentication/
self.current_user = find_verified_user
end
private
def find_verified_user
if verified_user = User.find_by(id: cookies.signed["user.id"])
verified_user
else
reject_unauthorized_connection
end
end
end
end
我在开发日志中没有看到An unauthorized connection attempt was rejected
错误,所以我想这肯定是问题所在。但是谷歌搜索该短语没有帮助。
如何缩小问题范围?
答案 0 :(得分:1)
在我看来,ActionCable部分正在工作,但是出现身份验证错误。 Successfully upgraded to WebSocket
表示它与用户建立了Websocket连接,但是An unauthorized connection attempt was rejected
表示您在代码中的某个位置拒绝了他们的连接。
检查您的connection.rb
文件,您在某个地方叫reject_unauthorized_connection
吗?
app / channels / application_cable / connection.rb
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 = env['warden'].user
current_user
else
reject_unauthorized_connection
end
end
end
end