在 Phoenix Framework 中使用自定义序列化程序,例如 MessagePack
Use custom serializer like MessagePack with Phoenix Framework
凤凰 1.3
使用 Erlang 20
编译的 Elixir 1.5.2
我有一个 Android 移动应用程序,它通过 HTTP 服务器发送和接收 MsgPack。现在我们计划在某些部分集成Phoenix框架。但是专门发送二进制文件 MsgPack 在 Phoenix 框架上很麻烦。
如何在 Phoenix 中使用 MsgPack 等自定义(反)序列化程序?
如果有任何相关性:
1. 使用 MsgPax 库
2. Checked this link 在 stoiximan.gr
我用 MsgPax 来做这个,效果很好。首先将其添加到您的 mix.exs 文件中。
接下来,要使用自定义序列化程序,您必须在 the transport function 的 user_socket.ex 文件中指定它,如下所示:
defmodule YourApp.UserSocket do
use Phoenix.Socket
# Your channels here
# Take out whichever version you're not using
## Transports for Phoenix 1.2
transport :websocket, Phoenix.Transports.WebSocket, timeout: 45_000,
serializer: YourApp.MsgpaxSerializer
## Transports for Phoenix 1.3
transport :websocket, Phoenix.Transports.WebSocket, timeout: 45_000,
serializer: [{YourApp.MsgpaxSerializer, "~> 2.0.0"}]
# Other user socket stuff
end
然后,作为 according to the docs, your serializer has to have 3 functions: decode!/2
, encode!/1
, and fastlane!/1
. So, copying mostly from phoenix's own implementation,您的序列化程序可能看起来像这样:
defmodule YourApp.MsgpaxSerializer do
@behaviour Phoenix.Transports.Serializer
alias Phoenix.Socket.Reply
alias Phoenix.Socket.Message
alias Phoenix.Socket.Broadcast
def fastlane!(%Broadcast{} = msg) do
msg = %Message{topic: msg.topic, event: msg.event, payload: msg.payload}
{:socket_push, :binary, encode_to_binary(msg)}
end
def encode!(%Reply{} = reply) do
msg = %Message{
topic: reply.topic,
event: "phx_reply",
ref: reply.ref,
payload: %{status: reply.status, response: reply.payload}
}
{:socket_push, :binary, encode_to_binary(msg)}
end
def encode!(%Message{} = msg) do
{:socket_push, :binary, encode_to_binary(msg)}
end
defp encode_to_binary(msg) do
msg |> Map.from_struct() |> Msgpax.pack!()
end
def decode!(message, _opts) do
message
|> Msgpax.unpack!()
|> Phoenix.Socket.Message.from_map!()
end
end
最后,如果您正在对结构进行编码,则可能必须将 @derive Msgpax.Packer
属性添加到包含结构的模块中,如 Msgpax's documentation 中所述。
凤凰 1.3
使用 Erlang 20
我有一个 Android 移动应用程序,它通过 HTTP 服务器发送和接收 MsgPack。现在我们计划在某些部分集成Phoenix框架。但是专门发送二进制文件 MsgPack 在 Phoenix 框架上很麻烦。
如何在 Phoenix 中使用 MsgPack 等自定义(反)序列化程序?
如果有任何相关性:
1. 使用 MsgPax 库
2. Checked this link 在 stoiximan.gr
我用 MsgPax 来做这个,效果很好。首先将其添加到您的 mix.exs 文件中。
接下来,要使用自定义序列化程序,您必须在 the transport function 的 user_socket.ex 文件中指定它,如下所示:
defmodule YourApp.UserSocket do
use Phoenix.Socket
# Your channels here
# Take out whichever version you're not using
## Transports for Phoenix 1.2
transport :websocket, Phoenix.Transports.WebSocket, timeout: 45_000,
serializer: YourApp.MsgpaxSerializer
## Transports for Phoenix 1.3
transport :websocket, Phoenix.Transports.WebSocket, timeout: 45_000,
serializer: [{YourApp.MsgpaxSerializer, "~> 2.0.0"}]
# Other user socket stuff
end
然后,作为 according to the docs, your serializer has to have 3 functions: decode!/2
, encode!/1
, and fastlane!/1
. So, copying mostly from phoenix's own implementation,您的序列化程序可能看起来像这样:
defmodule YourApp.MsgpaxSerializer do
@behaviour Phoenix.Transports.Serializer
alias Phoenix.Socket.Reply
alias Phoenix.Socket.Message
alias Phoenix.Socket.Broadcast
def fastlane!(%Broadcast{} = msg) do
msg = %Message{topic: msg.topic, event: msg.event, payload: msg.payload}
{:socket_push, :binary, encode_to_binary(msg)}
end
def encode!(%Reply{} = reply) do
msg = %Message{
topic: reply.topic,
event: "phx_reply",
ref: reply.ref,
payload: %{status: reply.status, response: reply.payload}
}
{:socket_push, :binary, encode_to_binary(msg)}
end
def encode!(%Message{} = msg) do
{:socket_push, :binary, encode_to_binary(msg)}
end
defp encode_to_binary(msg) do
msg |> Map.from_struct() |> Msgpax.pack!()
end
def decode!(message, _opts) do
message
|> Msgpax.unpack!()
|> Phoenix.Socket.Message.from_map!()
end
end
最后,如果您正在对结构进行编码,则可能必须将 @derive Msgpax.Packer
属性添加到包含结构的模块中,如 Msgpax's documentation 中所述。