我在一个简单的聊天应用程序中有一个service_echo
函数,它使用SockJS实现多用户私聊。我为在线用户列表创建了一个ETS表。通过存储SockJS会话,我想在每次收到来自不同Connection的消息时都向该Connection发送消息。
这是我的service_echo
代码。
service_echo(Conn, {recv, Data}, state) ->
Obj = mochijson2:decode(Data),
{struct, JsonData} = Obj,
Name = proplists:get_value(<<"name">>, JsonData),
A = ets:lookup(username,Name),
io:format("~p",[Conn]),
if
length(A) =:= 0 ->
ets:insert(username,{Name,Conn});
true ->
[{AA,BB}] = ets:lookup(username,Name),
BB:send(Data)
end,
io:format("hello");
即使Conn和BB相同,仍然Conn:send(data)
向浏览器发送有效数据,而BB:send(Data)
什么也不做,甚至没有显示错误。
由于我是Erlang的新手,请原谅我任何无意义的错误。
答案 0 :(得分:1)
首先,我建议你永远不要使用length(A) =:= 0
来测试列表A
是否为空;如果A
长列表,计算其元素将花费你很多,虽然结果实际上不会被使用。使用A =:= []
代替,更简单,更好。
我不明白为什么你说Conn
和BB
是一样的。这不符合您在此处发布的代码。如果表中没有Name
,则插入条目{Name, Conn}
。否则,如果表中存在Name
并且与单个对象BB
相关,则假设此BB
是一个模块,并且您调用其中定义的send
函数。
可能是你读错了if
的语义 - 如果是这样的话,不要让true
后卫混淆你,这就是if-then- else是用Erlang编写的。也许你想要有类似的东西:
...
A = ets:lookup(username,Name),
if
A =:= [] ->
ets:insert(username,{Name,Conn})
end,
[{_,BB}] = ets:lookup(username,Name),
BB:send(Data)
...
甚至更好:
...
A = ets:lookup(T,Name),
if
A =:= [] ->
ets:insert(T,{Name,Conn}),
BB = Conn;
true ->
[{_,BB}] = A
end,
BB:send(Data)
...
另一方面,可能是我误解了你想要做的事情。如果是这种情况,请澄清。