在Riak中存储ejabberd数据包

时间:2016-01-04 19:08:12

标签: erlang ejabberd riak

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

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

对于非常基本的和多个问题道歉,但是如果有人可以在这里发光,我们会感激不尽!

我用来尝试替换传入数据包中的“with \”的代码是:(它不起作用):

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

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

1 个答案:

答案 0 :(得分:1)

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数据包存储的所需内容。