【问题标题】:Erlang match integer then stringErlang 匹配整数然后字符串
【发布时间】:2018-10-06 03:57:27
【问题描述】:

我希望通过添加时间戳来更新我的 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)

【问题讨论】:

    标签: erlang pattern-matching


    【解决方案1】:

    将时间戳编码为固定长度前缀。您可以选择它是人类可读的还是二进制的。

    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}.
    

    【讨论】:

    • 感谢这个写得好的答案!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-12-26
    • 1970-01-01
    • 2014-11-25
    • 2021-02-22
    • 1970-01-01
    • 1970-01-01
    • 2016-04-28
    相关资源
    最近更新 更多