在 Riak 中存储 ejabberd 数据包

Storing ejabberd packets in Riak

我正在尝试在 Riak 中保存离线 ejabberd 消息。我早些时候在连接到 Riak 时遇到了问题,但现在在这个论坛的帮助下这些问题都得到了解决。但是现在,由于我对 Erlang / ejabberd 的理解有限,我无法将 ejabberd 数据包保存为字符串,然后放在 Riak 上。本质上,当 offline_message_hook 被锁存时,我采用 Packet 参数,然后想为每个双引号添加一个反斜杠,这样我就可以采用这个修改后的字符串并在 Riak 上保存为字符串值。但是,我似乎在努力修改传入的数据包以将“字符替换为 \”。

这是正确的方法吗?还是我的设计中遗漏了什么?我的应用程序依赖于 xml 格式,所以我应该改为使用 p1_xml 模块解析数据包并在将其存储到 Riak 之前使用提取的数据元素重建 xml。

对于非常基本和多个问题表示歉意,但如果有人可以在这里提出一些建议,我们将不胜感激!

我用来尝试将传入数据包中的“替换为 \”的代码是:(它不太有效):

NewPacket = re:replace(Packet, "\"", "\\"", [{return, list}, global]),

所以基本上,我会将 NewPacket 作为值传递给我的 Riak 调用。

ejabberd 与 Riak 兼容,它已经在 Riak 中存储数据包。例如,mod_offline 就是这样做的。

您可以直接查看 ejabberd 代码以了解如何执行此操作。例如,在 mod_offline 中,ejabberd 存储离线消息的方式如下:

store_offline_msg(Host, {User, _}, Msgs, Len, MaxOfflineMsgs,
                  riak) ->
    Count = if MaxOfflineMsgs =/= infinity ->
                    Len + count_offline_messages(User, Host);
               true -> 0
            end,
    if
        Count > MaxOfflineMsgs ->
            discard_warn_sender(Msgs);
        true ->
            lists:foreach(
              fun(#offline_msg{us = US,
                               timestamp = TS} = M) ->
                      ejabberd_riak:put(M, offline_msg_schema(),
                                        [{i, TS}, {'2i', [{<<"us">>, US}]}])
              end, Msgs)
    end.

ejabberd_riak:put/3的代码是:

put(Rec, RecSchema, IndexInfo) ->
    Key = encode_key(proplists:get_value(i, IndexInfo, element(2, Rec))),
    SecIdxs = [encode_index_key(K, V) ||
                  {K, V} <- proplists:get_value('2i', IndexInfo, [])],
    Table = element(1, Rec),
    Value = encode_record(Rec, RecSchema),
    case put_raw(Table, Key, Value, SecIdxs) of
        ok ->
            ok;
        {error, _} = Error ->
            log_error(Error, put, [{record, Rec},
                                   {index_info, IndexInfo}]),
            Error
    end.

put_raw(Table, Key, Value, Indexes) ->
    Bucket = make_bucket(Table),
    Obj = riakc_obj:new(Bucket, Key, Value, "application/x-erlang-term"),
    Obj1 = if Indexes /= [] ->
                   MetaData = dict:store(<<"index">>, Indexes, dict:new()),
                   riakc_obj:update_metadata(Obj, MetaData);
              true ->
                   Obj
           end,
    catch riakc_pb_socket:put(get_random_pid(), Obj1).

您应该已经具备适当的 API 功能,可以在 ejabberd 中执行有关 Riak 数据包存储的操作。