1

service_echo在一个简单的聊天应用程序中有一个函数,它使用 SockJS 来实现多用户私人聊天。我为在线用户列表创建了一个 ETS 表。通过存储 SockJS 会话,我想每当我收到来自不同连接的消息时向该连接发送消息。

这是我的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 的新手,请原谅我任何无意的错误。

4

1 回答 1

1

首先,我建议您不要使用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)
    ...

另一方面,可能是我误解了您要执行的操作。如果是这种情况,请澄清。

于 2013-08-27T22:55:35.957 回答