【问题标题】:"Elixir + phoenix" filtering websocket messages“Elixir + phoenix”过滤websocket消息
【发布时间】:2017-03-03 23:10:52
【问题描述】:

我尝试预处理 websocket 传入消息。在lobby_channel.ex 文件中我有:

defmodule Chatroom.LobbyChannel do
  use Phoenix.Channel

  def join("room:lobby", _payload, socket) do
    {:ok, socket}
  end
  def join("room:" <> _private_room_id, _params, _socket) do
    {:error, %{reason: "unauthorized"}}
  end

  def handle_in("new_move", payload, socket) do
    changeset = Chatroom.Move.changeset(%Chatroom.Move{}, payload)

    if changeset.valid? do
      broadcast! socket, "new_move", payload
      {:noreply, socket}
    else
      IO.puts "-----" <> changeset.errors[:message]
      push socket, "error", %{msg: "Invalid move"}
      {:noreply, socket}
    end
  end

  #intercept ["new_move"]
  #def handle_out("new_move", payload, socket) do
  #  IO.puts payload["name"] <> "=======" <> payload["message"]
  #  push socket, "new_move", payload
  #  {:noreply, socket}
  #end
end

模型文件包含验证函数:

...
def changeset(struct, params \\ %{}) do
  struct
  |> cast(params, [:name, :message])
  |> validate_required([:name, :message])
  |> validate_length(:name, min: 1)
  |> validate_length(:message, is: 2)
  |> is_move_allowed(params)
end

defp is_move_allowed(changeset, params) do
  IO.puts "--zz---" <> params["message"]

  if params["message"] == "00" do
    IO.puts "--yy---" <> params["message"]
    add_error(changeset, params["message"], "'message' cannot be '00'")
  else
    IO.puts "--xx---" <> params["message"]
    []
  end
end
...

..最后一个是我的自定义验证功能,我无法让它正常工作。我得到的输出:

--zz---00
--yy---00
[error] GenServer #PID<0.445.0> terminating
** (ArgumentError) argument error
    :erlang.byte_size(nil)
    (chatroom) web/channels/lobby_channel.ex:18: Chatroom.LobbyChannel.handle_in/3
    (phoenix) lib/phoenix/channel/server.ex:226: anonymous fn/4 in Phoenix.Channel.Server.handle_info/2
    (stdlib) gen_server.erl:601: :gen_server.try_dispatch/4
    (stdlib) gen_server.erl:667: :gen_server.handle_msg/5
    (stdlib) proc_lib.erl:247: :proc_lib.init_p_do_apply/3
Last message: %Phoenix.Socket.Message{event: "new_move", payload: %{"message" => "00", "name" => "a"}, ref: "2", to
pic: "room:lobby"}
State: %Phoenix.Socket{assigns: %{}, channel: Chatroom.LobbyChannel, channel_pid: #PID<0.445.0>, endpoint: Chatroom
.Endpoint, handler: Chatroom.UserSocket, id: nil, joined: true, pubsub_server: Chatroom.PubSub, ref: nil, serialize
r: Phoenix.Transports.WebSocketSerializer, topic: "room:lobby", transport: Phoenix.Transports.WebSocket, transport_
name: :websocket, transport_pid: #PID<0.439.0>}

据我了解,事情在逻辑上朝着正确的方向发展,消息包含正确的数据,但我该如何解决错误?我错过了什么?

【问题讨论】:

  • 尝试将 else 中的 [] 更改为 changeset
  • @Dogbert,同样的错误。对于“00”消息和所有其他
  • 能把web/channels/lobby_channel.ex的完整内容贴出来吗?
  • 啊,试试add_error(changeset, :message, "'message' cannot be '00'")
  • @Dogbert,谢谢,第三个错误是 IO.puts "-----" &lt;&gt; changeset.errors[:message] 应该替换为 inspectIO.inspect changeset.errors。您可以在主要答案中总结这 3 个修复,以便我接受它

标签: websocket elixir phoenix-framework


【解决方案1】:

代码中存在三个错误:

  1. is_move_allowed 必须始终返回变更集。你在 else 中返回 []

  2. add_error 的第二个参数应该是原子

  3. changeset.errors[:message] 是一个元组,因此您不能使用&lt;&gt; 将其与字符串连接。 IO.inspect 是更好的选择,因为它可以打印任何值。

所以,改变:

if params["message"] == "00" do
  IO.puts "--yy---" <> params["message"]
  add_error(changeset, params["message"], "'message' cannot be '00'")
else
  IO.puts "--xx---" <> params["message"]
  []
end

到:

if params["message"] == "00" do
  IO.puts "--yy---" <> params["message"]
  add_error(changeset, :message, "'message' cannot be '00'")
else
  IO.puts "--xx---" <> params["message"]
  changeset
end

并改变:

IO.puts "-----" <> changeset.errors[:message]

到:

IO.inspect changeset.errors[:message]
# or IO.inspect changeset.errors

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-01-12
    • 1970-01-01
    • 1970-01-01
    • 2016-12-05
    • 2017-04-05
    • 2018-05-22
    • 2017-02-05
    • 2019-07-07
    相关资源
    最近更新 更多