erlang, ejabberd, 如何处理 [{text, <<>>, <<"hello">>}] 格式
erlang, ejabberd, how to deal with [{text, <<>>, <<"hello">>}] formats
所以我的代码中有一个钩子,表示如果收到离线消息,它将启动此功能。
offline_msg_received(From, To, Packet) ->
数据包的代码如下所示:
{message,<<"purple2d957668">>,chat,<<>>,undefined,{jid,<<"admin">>,<<"localhost">>,<<"5280">>,<<"admin">>,<<"localhost">>,<<"5280">>},[],[{text,<<>>,<<"Hello">>}],undefined,[{xmlel,<<"active">>,[{<<"xmlns">>,<<"http://jabber.org/protocol/chatstates">>}],[]}],#{}}
我想要的是包含我的信息的部分。即:
[{text,<<>>,<<"Hello">>}]
我可以通过对整个包变量进行模式匹配来得到这部分。但是,当我尝试与我的消息匹配的模式时,它说错误的论点。我知道如果我只用
指定一个变量
{text,<<>>,<<"Hello">>}
然后我可以对其进行模式匹配。根据我的理解,在某物周围看到 [ ] 表示它是一个列表或字符串。
我可以在这里展示一些代码。
{P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11} = Packet, %% P8 is the message I want.
?INFO_MSG("----------------------P8: ~p~n", P8), %% This shows {text,<<>>,<<"Hello">>}
{A, B, C} = P8, %% This gives me a badmatch error.
现在,如果我改为在代码中手动执行此操作 shell:
{text,<<>>,<<"Hello">>} = P8,
{A, B, C} = P8,
然后代码运行,并将 <<"Hello">> 放入 C 变量中。
我的猜测是 "Package" 变量中它周围的 [ ] 与我的不匹配错误有关,但由于某些原因,当我打印出 P8 时,这些符号没有出现。有没有人有一个很好的建议为什么它不起作用?我猜它与隐藏的 [ ] 有关,否则它看起来与我的 shell 代码测试相同。
谢谢。这是我第一次在这里提问,所以我希望我没有做错什么。
您在 INFO_MSG
调用中看不到值周围的方括号的原因是 INFO_MSG
需要一个 list 值,而不是只是一个单一的价值。在上面的代码中它恰好可以解决,因为格式字符串只包含一个指令,并且值是一个元素的列表,所以这就是为什么括号被默默地去掉的原因。
INFO_MSG
宏的工作原理与 io:format
相同,因此您可以在 shell:
中尝试这个
%% two arguments
io:format("~p ~p\n", [foo, bar]).
%% one argument - we still need square brackets
io:format("~p\n", [foo]).
你这样做很困难:) message
和 text
是在 xmpp_codec.hrl 中定义的记录。如果您没有在 shell 中加载记录定义,记录看起来像一个包含很多元素的元组,但如果您加载记录定义,您的消息将如下所示:
1> rr("include/xmpp_codec.hrl").
[address,addresses,adhoc_actions,adhoc_command,adhoc_note,
bind,block,block_list,bob_data,bookmark_conference,
bookmark_storage,bookmark_url,bytestreams,caps,
carbons_disable,carbons_enable,carbons_private,
carbons_received,carbons_sent,chatstate,client_id,compress,
compress_failure,compressed,compression,csi,db_feature,
db_result,db_verify|...]
2> {message,<<"purple2d957668">>,chat,<<>>,undefined,{jid,<<"admin">>,<<"localhost">>,<<"5280">>,<<"admin">>,<<"localhost">>,<<"5280">>},[],[{text,<<>>,<<"Hello">>}],undefined,[{xmlel,<<"active">>,[{<<"xmlns">>,<<"http://jabber.org/protocol/chatstates">>}],[]}],#{}}.
#message{id = <<"purple2d957668">>,type = chat,lang = <<>>,
from = undefined,
to = {jid,<<"admin">>,<<"localhost">>,<<"5280">>,
<<"admin">>,<<"localhost">>,<<"5280">>},
subject = [],
body = [#text{lang = <<>>,data = <<"Hello">>}],
thread = undefined,
sub_els = [{xmlel,<<"active">>,
[{<<"xmlns">>,
<<"http://jabber.org/protocol/chatstates">>}],
[]}],
meta = #{}}
您要查找的数据在 body
字段中。
让我们将此记录分配给变量M
并提取正文字段:
4> Body = M#message.body.
[#text{lang = <<>>,data = <<"Hello">>}]
所以这是一个包含一条 text
记录的列表。让我们从中提取 data
字段:
6> [#text{data = Data}] = Body.
[#text{lang = <<>>,data = <<"Hello">>}]
7> Data.
<<"Hello">>
这就是它在 shell 中的工作方式 - 使用 rr
函数加载记录定义。在编写使用记录定义的模块时,您需要包含 hrl
文件:
-include_lib("xmpp/include/xmpp_codec.hrl").
-include_lib
目录将在加载路径上查找 xmpp
应用程序,并在其 include
目录中搜索文件 xmpp_codec.hrl
。您可能需要指定编译器的代码路径,例如 erlc -pa path/to/xmpp/ebin my_module.erl
- 请注意,应用程序内的 ebin
目录应该在代码路径上。
所以我的代码中有一个钩子,表示如果收到离线消息,它将启动此功能。
offline_msg_received(From, To, Packet) ->
数据包的代码如下所示:
{message,<<"purple2d957668">>,chat,<<>>,undefined,{jid,<<"admin">>,<<"localhost">>,<<"5280">>,<<"admin">>,<<"localhost">>,<<"5280">>},[],[{text,<<>>,<<"Hello">>}],undefined,[{xmlel,<<"active">>,[{<<"xmlns">>,<<"http://jabber.org/protocol/chatstates">>}],[]}],#{}}
我想要的是包含我的信息的部分。即:
[{text,<<>>,<<"Hello">>}]
我可以通过对整个包变量进行模式匹配来得到这部分。但是,当我尝试与我的消息匹配的模式时,它说错误的论点。我知道如果我只用
指定一个变量{text,<<>>,<<"Hello">>}
然后我可以对其进行模式匹配。根据我的理解,在某物周围看到 [ ] 表示它是一个列表或字符串。
我可以在这里展示一些代码。
{P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11} = Packet, %% P8 is the message I want.
?INFO_MSG("----------------------P8: ~p~n", P8), %% This shows {text,<<>>,<<"Hello">>}
{A, B, C} = P8, %% This gives me a badmatch error.
现在,如果我改为在代码中手动执行此操作 shell:
{text,<<>>,<<"Hello">>} = P8,
{A, B, C} = P8,
然后代码运行,并将 <<"Hello">> 放入 C 变量中。
我的猜测是 "Package" 变量中它周围的 [ ] 与我的不匹配错误有关,但由于某些原因,当我打印出 P8 时,这些符号没有出现。有没有人有一个很好的建议为什么它不起作用?我猜它与隐藏的 [ ] 有关,否则它看起来与我的 shell 代码测试相同。
谢谢。这是我第一次在这里提问,所以我希望我没有做错什么。
您在 INFO_MSG
调用中看不到值周围的方括号的原因是 INFO_MSG
需要一个 list 值,而不是只是一个单一的价值。在上面的代码中它恰好可以解决,因为格式字符串只包含一个指令,并且值是一个元素的列表,所以这就是为什么括号被默默地去掉的原因。
INFO_MSG
宏的工作原理与 io:format
相同,因此您可以在 shell:
%% two arguments
io:format("~p ~p\n", [foo, bar]).
%% one argument - we still need square brackets
io:format("~p\n", [foo]).
你这样做很困难:) message
和 text
是在 xmpp_codec.hrl 中定义的记录。如果您没有在 shell 中加载记录定义,记录看起来像一个包含很多元素的元组,但如果您加载记录定义,您的消息将如下所示:
1> rr("include/xmpp_codec.hrl").
[address,addresses,adhoc_actions,adhoc_command,adhoc_note,
bind,block,block_list,bob_data,bookmark_conference,
bookmark_storage,bookmark_url,bytestreams,caps,
carbons_disable,carbons_enable,carbons_private,
carbons_received,carbons_sent,chatstate,client_id,compress,
compress_failure,compressed,compression,csi,db_feature,
db_result,db_verify|...]
2> {message,<<"purple2d957668">>,chat,<<>>,undefined,{jid,<<"admin">>,<<"localhost">>,<<"5280">>,<<"admin">>,<<"localhost">>,<<"5280">>},[],[{text,<<>>,<<"Hello">>}],undefined,[{xmlel,<<"active">>,[{<<"xmlns">>,<<"http://jabber.org/protocol/chatstates">>}],[]}],#{}}.
#message{id = <<"purple2d957668">>,type = chat,lang = <<>>,
from = undefined,
to = {jid,<<"admin">>,<<"localhost">>,<<"5280">>,
<<"admin">>,<<"localhost">>,<<"5280">>},
subject = [],
body = [#text{lang = <<>>,data = <<"Hello">>}],
thread = undefined,
sub_els = [{xmlel,<<"active">>,
[{<<"xmlns">>,
<<"http://jabber.org/protocol/chatstates">>}],
[]}],
meta = #{}}
您要查找的数据在 body
字段中。
让我们将此记录分配给变量M
并提取正文字段:
4> Body = M#message.body.
[#text{lang = <<>>,data = <<"Hello">>}]
所以这是一个包含一条 text
记录的列表。让我们从中提取 data
字段:
6> [#text{data = Data}] = Body.
[#text{lang = <<>>,data = <<"Hello">>}]
7> Data.
<<"Hello">>
这就是它在 shell 中的工作方式 - 使用 rr
函数加载记录定义。在编写使用记录定义的模块时,您需要包含 hrl
文件:
-include_lib("xmpp/include/xmpp_codec.hrl").
-include_lib
目录将在加载路径上查找 xmpp
应用程序,并在其 include
目录中搜索文件 xmpp_codec.hrl
。您可能需要指定编译器的代码路径,例如 erlc -pa path/to/xmpp/ebin my_module.erl
- 请注意,应用程序内的 ebin
目录应该在代码路径上。