我有一个 service_echo
一个简单的聊天应用程序中的函数,它使用 SockJS 实现多用户私有(private)聊天。我为在线用户列表创建了一个 ETS 表。通过存储 SockJS session ,每当我收到来自不同连接的消息时,我想向该连接发送消息。
这是我的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 的新手,请原谅我任何无意的错误。
最佳答案
首先,让我建议你不要使用 length(A) =:= 0
用于测试列表 A
是否为空;如果 A
一个很长的列表,计算它的元素会花费你很多,尽管结果实际上不会被使用。使用A =:= []
相反,更简单更好。
我不明白你为什么这么说Conn
和 BB
是相同的。这与您在此处发布的代码不同。如果 Name
不在表中,您插入一个条目 {Name, Conn}
.否则,如果 Name
存在于表中并且与单个对象有关BB
, 你假设这个 BB
是一个模块,您调用 send
其中定义的功能。
可能是您读错了 if
的语义。 --- 如果是这样,不要让 true
守卫让你感到困惑,这就是用 Erlang 编写 if-then-else 的方式。也许您想要类似的东西:
...
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)
...
另一方面,可能是我误解了您要执行的操作。如果是这种情况,请澄清。
关于sockets - Erlang 变量模式匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18223531/