凤凰1.3 使用Erlang 20编译的Elixir 1.5.2
我有一个Android移动应用程序,它通过HTTP服务器发送和接收MsgPack。现在我们计划将Phoenix框架集成到某些部分。但是发送二进制文件特别是MsgPack在Phoenix框架上很麻烦。
如何使用凤凰城的MsgPack等自定义(反)序列化器?
如果有任何相关性:
1.使用MsgPax库
2. Checked this link on stoiximan.gr
答案 0 :(得分:2)
我已经使用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,您的序列化程序必须具有3个函数:decode!/2
,encode!/1
和fastlane!/1
。因此,主要从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中所述。