我是一个二郎新手。我尝试使用gen_udp构建服务器以维护在线客户端的在线/离线状态。所有客户端都将udp数据发送到udp服务器,服务器从所有客户端接收udp数据,如果服务器在5秒内没有收到数据,则服务器标记该客户端脱机。
-module(client_states_manager).
-export([start/0]).
start() ->
spawn(fun() -> server(8080) end).
server(Port) ->
{ok, Socket} = gen_udp:open(Port, [binary, {active, false}]),
io:format("server opened socket:~p~n",[Socket]),
loop(Socket).
loop(Socket) ->
inet:setopts(Socket, [{active, once}]),
receive
{udp, Socket, Host, Port, Bin} ->
io:format("server received:~p from ~w~n",[Bin, Host]),
%%% How to detect if Host is in a list variable (lists:member), if Host is not already in OnlineHosts variable, lists:append it to OnlineHosts
%gen_udp:send(Socket, Host, Port, Bin),
loop(Socket)
end.
displayOnlineHosts(Hosts) ->
io:format("There are online hosts ~p~n",[Hosts]).
这是用于测试的客户端ruby脚本:
require "socket"
sender = UDPSocket.new
host = ARGV[0]
port = ARGV[1] || 8080
puts "Connect to #{host}:#{port}"
n = 0
loop do
sender.send("message #{n}", 0, host, port)
n = n + 1
end
谁会给我一些启动的灵感?非常感谢。
答案 0 :(得分:0)
您必须将OnlineHosts
变量传递给loop
函数并相应地更新其值。可能是这样的:
server(Port) ->
{ok, Socket} = gen_udp:open(Port, [binary, {active, false}]),
io:format("server opened socket:~p~n",[Socket]),
loop(Socket, []).
loop(Socket, OnlineHosts) ->
inet:setopts(Socket, [{active, once}]),
receive
{udp, Socket, Host, Port, Bin} ->
io:format("server received:~p from ~w~n",[Bin, Host]),
%%% How to detect if Host is in a list variable (lists:member), if Host is not already in OnlineHosts variable, lists:append it to OnlineHosts
case lists:member(Host, OnlineHosts) of
true ->
loop(Socket, OnlineHosts);
false ->
%gen_udp:send(Socket, Host, Port, Bin),
loop(Socket, [Host | OnlineHosts])
end
end.