我希望通过添加时间戳来更新我的Erlang服务器。以前,我有命令然后将参数发送到服务器:
server_loop(Socket) ->
inet:setopts(Socket, [{active, once}]),
receive
{tcp, Socket, <<"read", Content/binary>>} ->
error_logger:info_msg("Reading ~w", [Content]),
read(Socket, Content),
server_loop(Socket);
{tcp, Socket, <<"up", Content/binary>>} ->
update(Socket, Content),
server_loop(Socket);
...
end
如您所见,我根据消息的第一个关键字将消息发送到正确的方法。
现在,我的客户端在命令之前发送时间戳(以os:system_time()
为单位)。
我怎么能匹配我的消息,比如“ANY_TIMESTAMP read”,“ANY_TIMESTAMP up”,......仍然可以将它传递给我的方法,如read(Socket, Timestamp, Content)
?
答案 0 :(得分:4)
将时间戳编码为固定长度前缀。您可以选择它是人类可读还是二进制。
make_read_packet(Timestamp, Content) ->
<<Timestamp:64, "read", Content/bytes>>.
或
-define(TIMESTAMP_LENGTH, 20). % or any suitable size
make_read_packet(Timestamp, Content) ->
B = integer_to_binary(Timestamp),
P = binary:copy(<<$0>>, ?TIMESTAMP_LENGTH - byte_size(B)),
<<P/bytes, B/bytes, "read", Content/bytes>>.
然后您可以轻松检测到它
{tcp, Socket, <<Timestamp:64, "read", Content/binary>>} ->
error_logger:info_msg("Reading ~w", [Content]),
read(Socket, Timestamp, Content),
server_loop(Socket);
或
{tcp, Socket, <<TBin:?TIMESTAMP_LENGTH/bytes, "read", Content/binary>>} ->
try binary_to_integer(TBin) of
Timestamp ->
error_logger:info_msg("Reading ~w", [Content]),
read(Socket, Timestamp, Content)
catch error:badarg -> badarg end,
server_loop(Socket);
否则,你需要像
这样的东西 {tcp, Socket, Packet} ->
case parse_timestamp(Packet) of
{Timestamp, <<"read", Content/bytes>>} ->
error_logger:info_msg("Reading ~w", [Content]),
read(Socket, Timestamp, Content);
_ -> error
end,
server_loop(Socket);
parse_timestamp(Packet) ->
parse_timestamp(Packet, 0).
parse_timestamp(<<D, Rest/bytes>>, N) when D >= $0, D <= $9 ->
parse_timestamp(Rest, 10 * N + D - $0);
parse_timestamp(Rest, N) -> {N, Rest}.