Phoenix Channel - 连接时的Erlang KeyError

时间:2015-12-29 16:16:40

标签: elixir phoenix-framework

我正在阅读编程凤凰书,并在尝试连接到经过身份验证的频道时遇到服务器错误。错误是:

[error] Process #PID<0.1000.0> raised an exception ** (ErlangError) erlang error: [reason: %KeyError{key: :user_id, term: %{current_user: %Rumbl.User{__meta__: #Ecto.Schema.Metadata<:loaded>, annotations: #Ecto.Association.NotLoaded<association :annotations is not loaded>, id: 6, inserted_at: #Ecto.DateTime<2015-12-14T17:57:37Z>, name: "Joe", password: nil, password_hash: "$2b$12$TkUgAyJvSroft6KNhs8ECukFkrREZ/jS2xZUTLdp3oQuV.px22WrS", updated_at: #Ecto.DateTime<2015-12-14T17:57:37Z>, username: "joe", videos: #Ecto.Association.NotLoaded<association :videos is not loaded>}}}, mfa: {Phoenix.Endpoint.CowboyWebSocket, :init, 3}, stacktrace: [{Rumbl.UserSocket, :id, 1, [file: 'web/channels/user_socket.ex', line: 46]}, {Phoenix.Socket.Transport, :connect_vsn, 6, [file: 'lib/phoenix/socket/transport.ex', line: 154]}, {Phoenix.Transports.WebSocket, :init, 2, [file: 'lib/phoenix/transports/websocket.ex', line: 73]}, {Phoenix.Endpoint.CowboyWebSocket, :init, 3, [file: 'lib/phoenix/endpoint/cowboy_websocket.ex', line: 11]}, {:cowboy_handler, :handler_init, 4, [file: 'src/cowboy_handler.erl', line: 64]}, {:cowboy_protocol, :execute, 4, [file: 'src/cowboy_protocol.erl', line: 442]}], req: [socket: #Port<0.60203>, transport: :ranch_tcp, connection: :keepalive, pid: #PID<0.1000.0>, method: "GET", version: :"HTTP/1.1", peer: {{127, 0, 0, 1}, 49668}, host: "localhost", host_info: :undefined, port: 4000, path: "/socket/websocket", path_info: :undefined, qs: "token=g3QAAAACZAAEZGF0YWEGZAAGc2lnbmVkbgYA57J57lEB--NwLr3U3AgY8nAsNdr7Uya86zUrE%3D&vsn=1.0.0", qs_vals: :undefined, bindings: [], headers: [{"host", "localhost:4000"}, {"connection", "Upgrade"}, {"pragma", "no-cache"}, {"cache-control", "no-cache"}, {"upgrade", "websocket"}, {"origin", "http://localhost:4000"}, {"sec-websocket-version", "13"}, {"user-agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36"}, {"accept-encoding", "gzip, deflate, sdch"}, {"accept-language", "en-US,en;q=0.8"}, {"cookie", "SnapABugHistory=1#; _ga=GA1.1.577046204.1438865191; access_token=f4070d3a1906ebff569d311aa0ddd842c8ef30ee; user-hash=d569532a977f78e1d96d5bab3412a265; SnapABugVisit=86#1449075542; _rumbl_key=g3QAAAACbQAAAAtfY3NyZl90b2tlbm0AAAAYRUoxM1A2NnNNelRoSkR1TGxjaWM2UT09bQAAAAd1c2VyX2lkYQY=--P7j+4zmpEx4KRG4Eq5xZXruIM0Y="}, {"sec-websocket-key", "XjCnurWNHP47g1gcmQN5LA=="}, {"sec-websocket-extensions", "permessage-deflate; client_max_window_bits"}], p_headers: [{"connection", ["upgrade"]}], cookies: :undefined, meta: [], body_state: :waiting, buffer: "", multipart: :undefined, resp_compress: false, resp_state: :waiting, resp_headers: [], resp_body: "", onresponse: :undefined], opts: {Phoenix.Transports.WebSocket, {Rumbl.Endpoint, Rumbl.UserSocket, :websocket}}] (cowboy) src/cowboy_protocol.erl:442: :cowboy_protocol.execute/4 [error] Ranch protocol #PID<0.1000.0> (:cowboy_protocol) of listener Rumbl.Endpoint.HTTP terminated ** (exit) an exception was raised: ** (ErlangError) erlang error: [reason: %KeyError{key: :user_id, term: %{current_user: %Rumbl.User{__meta__: #Ecto.Schema.Metadata<:loaded>, annotations: #Ecto.Association.NotLoaded<association :annotations is not loaded>, id: 6, inserted_at: #Ecto.DateTime<2015-12-14T17:57:37Z>, name: "Joe", password: nil, password_hash: "$2b$12$TkUgAyJvSroft6KNhs8ECukFkrREZ/jS2xZUTLdp3oQuV.px22WrS", updated_at: #Ecto.DateTime<2015-12-14T17:57:37Z>, username: "joe", videos: #Ecto.Association.NotLoaded<association :videos is not loaded>}}}, mfa: {Phoenix.Endpoint.CowboyWebSocket, :init, 3}, stacktrace: [{Rumbl.UserSocket, :id, 1, [file: 'web/channels/user_socket.ex', line: 46]}, {Phoenix.Socket.Transport, :connect_vsn, 6, [file: 'lib/phoenix/socket/transport.ex', line: 154]}, {Phoenix.Transports.WebSocket, :init, 2, [file: 'lib/phoenix/transports/websocket.ex', line: 73]}, {Phoenix.Endpoint.CowboyWebSocket, :init, 3, [file: 'lib/phoenix/endpoint/cowboy_websocket.ex', line: 11]}, {:cowboy_handler, :handler_init, 4, [file: 'src/cowboy_handler.erl', line: 64]}, {:cowboy_protocol, :execute, 4, [file: 'src/cowboy_protocol.erl', line: 442]}], req: [socket: #Port<0.60203>, transport: :ranch_tcp, connection: :keepalive, pid: #PID<0.1000.0>, method: "GET", version: :"HTTP/1.1", peer: {{127, 0, 0, 1}, 49668}, host: "localhost", host_info: :undefined, port: 4000, path: "/socket/websocket", path_info: :undefined, qs: "token=g3QAAAACZAAEZGF0YWEGZAAGc2lnbmVkbgYA57J57lEB--NwLr3U3AgY8nAsNdr7Uya86zUrE%3D&vsn=1.0.0", qs_vals: :undefined, bindings: [], headers: [{"host", "localhost:4000"}, {"connection", "Upgrade"}, {"pragma", "no-cache"}, {"cache-control", "no-cache"}, {"upgrade", "websocket"}, {"origin", "http://localhost:4000"}, {"sec-websocket-version", "13"}, {"user-agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36"}, {"accept-encoding", "gzip, deflate, sdch"}, {"accept-language", "en-US,en;q=0.8"}, {"cookie", "SnapABugHistory=1#; _ga=GA1.1.577046204.1438865191; access_token=f4070d3a1906ebff569d311aa0ddd842c8ef30ee; user-hash=d569532a977f78e1d96d5bab3412a265; SnapABugVisit=86#1449075542; _rumbl_key=g3QAAAACbQAAAAtfY3NyZl90b2tlbm0AAAAYRUoxM1A2NnNNelRoSkR1TGxjaWM2UT09bQAAAAd1c2VyX2lkYQY=--P7j+4zmpEx4KRG4Eq5xZXruIM0Y="}, {"sec-websocket-key", "XjCnurWNHP47g1gcmQN5LA=="}, {"sec-websocket-extensions", "permessage-deflate; client_max_window_bits"}], p_headers: [{"connection", ["upgrade"]}], cookies: :undefined, meta: [], body_state: :waiting, buffer: "", multipart: :undefined, resp_compress: false, resp_state: :waiting, resp_headers: [], resp_body: "", onresponse: :undefined], opts: {Phoenix.Transports.WebSocket, {Rumbl.Endpoint, Rumbl.UserSocket, :websocket}}] (cowboy) src/cowboy_protocol.erl:442: :cowboy_protocol.execute/4

user_socket.ex的第46行是:

def id(socket), do: "users_socket:#{socket.assigns.user_id}"

我在这里缺少什么?谢谢!

1 个答案:

答案 0 :(得分:1)

据报道,这是一个错误的here,所以我相信它会在本书的最终版本中修复。要解决此问题,请更改:

def id(socket), do: "users_socket:#{socket.assigns.user_id}"

为:

def id(socket), do: "users_socket:#{socket.assigns.current_user.id}"

为什么会收到此错误

UserSocket connect/2中,如果用户经过身份验证,则您将current_user分配给套接字中的user而不是user_id

{:ok, assign(socket, :current_user, user)}

因此socket没有user_id密钥。调用地图中不存在的密钥时会引发KeyError错误:

enter image description here