我刚使用file:write
转储此变量:
file:write_file("/tmp/foo.txt", io_lib:fwrite("~p.\n", [Message])),
这是emqtt中插件代码的一部分。 我想解析这个内容,并在一个名为topic的变量中将消息变量和home / garden / fountain中的部分sdfjksdf。这该怎么做。我不知道二郎。
{mqtt_message,<<0,5,101,163,106,150,123,212,110,126,0,0,76,244,0,3>>,
undefined,
{<<"1852fadb884d46c7a349f6a974846ce1">>,undefined},
<<"home/garden/fountain">>,0,[],false,false,false,[],
<<"sdfjksdf">>,
{1519,127425,874902}}
这是我遇到问题的功能
on_message_publish(Message, _Env) ->
io:format("publish ~s~n", [emqttd_message:format(Message)]),
file:write_file("/tmp/foo.txt", io_lib:fwrite("~p.\n", [Message])),
inets:start(),
Method = post,
URL = "http://xyz.in/api/v2/mysql/_table/device",
Header = [{"Api-Key", "1234"}],
Type = "application/json",
Body = "{\"resource\":[{\"deviceid\":\"" ++ "msg" ++ "\"}]}",
HTTPOptions = [],
Options = [],
R = httpc:request(Method, {URL, Header, Type, Body}, HTTPOptions, Options),
{ok, Message}.
在上面的代码中,我必须传递字符串&#34; sdfjksdf&#34;来自Message对象并代替&#34; msg&#34;串。 我试过++ element(12,Message)++但它不起作用。
然后我尝试了++ binary_to_list(element(12,Message))++这也不起作用。
我如何传递字符串&#34; sdfjksdf&#34;来自Message对象通过连接传递给JSON字符串中作为参数的函数。
答案 0 :(得分:3)
这是二郎中的一个元组。见:http://erlang.org/doc/reference_manual/data_types.html。这是元组在一个单独的行上组织的元组:
{
mqtt_message,
<<0,5,101,163,106,150,123,212,110,126,0,0,76,244,0,3>>,
undefined,
{<<"1852fadb884d46c7a349f6a974846ce1">>,undefined},
<<"home/garden/fountain">>,
0,
[],
false,
false,
false,
[],
<<"sdfjksdf">>,
{1519,127425,874902}
}
元组中第一个元素的索引是1.所以你可以这样做:
8> Data = f:get_data().
{mqtt_message,<<0,5,101,163,106,150,123,212,110,126,0,0,
76,244,0,3>>,
undefined,
{<<"1852fadb884d46c7a349f6a974846ce1">>,undefined},
<<"home/garden/fountain">>,0,[],false,false,false,[],
<<"sdfjksdf">>,
{1519,127425,874902}}
9> Message = element(12, Data).
<<"sdfjksdf">>
10> Topic = element(5, Data).
<<"home/garden/fountain">>
对评论的回应:
还可以告诉你&lt;&lt;&gt;&gt;的含义是什么?上面的符号 元组
如果您在上面发布的链接中搜索了所有erlang数据类型的链接,那么您会发现这样的元素:
<<"sdfjksdf">>
称为二进制。二进制文件就像字符串一样,但对于二进制文件,erlang提供了一种语法,允许您将二进制文件切割成您想要的任何大小的块。这对于读取通过网络发送的字符串非常有用,前4位可以表示整个消息的长度,接下来的12位代表一些信息,接下来的3位代表其他一些信息等。
但是因为二进制文件也比字符串更有效,即使你不需要将字符串分割成其组成位,你也可以将字符串转换为二进制文件并传递它们。 erlang中的所有I / O工具都可以比字符串更有效地处理二进制文件。
但是,如果由于某种原因需要将二进制文件作为字符串,则可以使用函数binary_to_list()
将二进制文件转换为字符串。在erlang中,字符串实际上是 list ,其中包含整数字符代码:
9> [97,98,99].
"abc"
...因此名称为binary_to_list。
以下是将二进制文件转换为字符串的示例:
7> TopicBin = <<"home/garden/fountain">>.
<<"home/garden/fountain">>
8> TopicStr = binary_to_list(TopicBin).
"home/garden/fountain"
9>
回复编辑:
我试过
++ element(12,Message) ++
但它不起作用。
我们已经确定element(12, Message
)的返回值是二进制值,但您应该检查以确保:
X = element(12, Message),
io:format("What is this: ~w~n", [X])
接下来,++
运算符是string:concat()的快捷方式,它需要字符串参数,因此您不能将++
与二进制文件一起使用。
然后我尝试
++ binary_to_list(element(12,Message)) ++
这也不起作用。
这有效:
2> Msg = "sdfjksdf".
"sdfjksdf"
3> Result = "hello " ++ Msg ++ " world".
"hello sdfjksdf world"
之前,我们讨论过如何将二进制文件转换为字符串(列表)。所以,你可以这样做:
5> Bin = <<"sdfjksdf">>.
<<"sdfjksdf">>
6> Msg = binary_to_list(Bin).
"sdfjksdf"
7> "hello " ++ Msg ++ " world".
而且,最后一行相当于:
8> "hello " ++ binary_to_list(Bin) ++ " world".
"hello sdfjksdf world"
这里面是你的功能:
-module(f).
-compile(export_all).
get_message() ->
{
mqtt_message,
<<0,5,101,163,106,150,123,212,110,126,0,0,76,244,0,3>>,
undefined,
{<<"1852fadb884d46c7a349f6a974846ce1">>,undefined},
<<"home/garden/fountain">>,
0,
[],
false,
false,
false,
[],
<<"sdfjksdf">>,
{1519,127425,874902}
}.
on_message_publish(Message, _Env) ->
%io:format("publish ~s~n", [emqttd_message:format(Message)]),
%file:write_file("/tmp/foo.txt", io_lib:fwrite("~p.\n", [Message])),
%inets:start(),
DeviceIdBin = element(12, Message),
DeviceIdStr = binary_to_list(DeviceIdBin),
Method = post,
URL = "http://xyz.in/api/v2/mysql/_table/device",
Header = [{"Api-Key", "1234"}],
Type = "application/json",
Body = "{\"resource\":[{\"deviceid\":\"" ++ DeviceIdStr ++ "\"}]}",
io:format("Body=~s~n", [Body]),
%HTTPOptions = [],
%Options = [],
%R = httpc:request(Method, {URL, Header, Type, Body}, HTTPOptions, Options),
{ok, Message}.
go() ->
Message = get_message(),
on_message_publish(Message, "hello").
在erlang shell中:
5> c(f).
f.erl:29: Warning: variable 'Method' is unused
f.erl:30: Warning: variable 'URL' is unused
f.erl:31: Warning: variable 'Header' is unused
f.erl:32: Warning: variable 'Type' is unused
{ok,f}
6> f:go().
Body={"resource":[{"deviceid":"sdfjksdf"}]}
{ok,{mqtt_message,<<0,5,101,163,106,150,123,212,110,126,0,
0,76,244,0,3>>,
undefined,
{<<"1852fadb884d46c7a349f6a974846ce1">>,undefined},
<<"home/garden/fountain">>,0,[],false,false,false,[],
<<"sdfjksdf">>,
{1519,127425,874902}}}
7>
答案 1 :(得分:0)
该类型称为tuple
,是一种Erlang数据类型。您通常可以将其视为固定长度的数组。 Erlang元组是1索引的。有几种方法可以从元组中提取数据。如果您知道元组的大小,例如:
{_,_,_,_,Message,_,_,_,_,_,_,Topic,_} = {mqtt_message,<<0,5,101,163,106,150,123,212,110,126,0,0,76,244,0,3>>,
undefined,
{<<"1852fadb884d46c7a349f6a974846ce1">>,undefined},
<<"home/garden/fountain">>,0,[],false,false,false,[],
<<"sdfjksdf">>,
{1519,127425,874902}}.
这将分别将您想要的数据绑定到Message和Topic变量。或者使用内置函数element
:
element(5, {mqtt_message,<<0,5,101,163,106,150,123,212,110,126,0,0,76,244,0,3>>,
undefined,
{<<"1852fadb884d46c7a349f6a974846ce1">>,undefined},
<<"home/garden/fountain">>,0,[],false,false,false,[],
<<"sdfjksdf">>,
{1519,127425,874902}})
或:
element(12, {mqtt_message,<<0,5,101,163,106,150,123,212,110,126,0,0,76,244,0,3>>,
undefined,
{<<"1852fadb884d46c7a349f6a974846ce1">>,undefined},
<<"home/garden/fountain">>,0,[],false,false,false,[],
<<"sdfjksdf">>,
{1519,127425,874902}})
我希望这能回答你的问题,干杯!
编辑:
<<>>
是一个Erlang二进制文件,这是一个非常大的主题。您可以阅读有关数据类型和内置二进制操作here的信息。
EDIT2:
我不完全确定你对原帖的最后编辑是什么意思。但是,如果您只想提取二进制文件<<"sdfjksdf">>
并将其附加到现有字符串:
42> Msg = binary:bin_to_list(element(12,Message)).
"sdfjksdf"
43> "test: " ++ Msg.
"test: sdfjksdf"
您需要找出使用该语法将其附加到JSON正文中的正确方法。请记住,++
操作对大型列表无效。