chat节点实现的原理和holl节点实现的原理大致相同。都是从node_connect节点上得到数据,处理之后,把其节点上的数据发给node_connect节点,通过node_connect节点与客户
chat节点实现的原理和holl节点实现的原理大致相同。都是从node_connect节点上得到数据,处理之后,把其节点上的数据发给node_connect节点,通过node_connect节点与客户端进行交互。
chat节点的源码如下
%% @author cb1187
%% @doc @todo Add description to opt_chat.
-module(opt_chat).
%% ====================================================================
%% API functions
%% ====================================================================
-behaviour(gen_server).
-export([]).
%% gen_server callbacks
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
terminate/2, code_change/3]).
-compile(export_all).
-define(Ets_Users,opt_chat_ets_users).
-define(Server_Chat,chat).
-define(Node_Node,node@simsunny).
-define(Server_Node,node).
-define(Node_Holl,holl@simsunny).
-define(Server_Holl,holl).
%% ====================================================================
%% Internal functions
%% ====================================================================
s() -> gen_server:start_link({local,?Server_Chat}, ?MODULE, [], []).
stop() -> gen_server:call(?Server_Chat, stop).
init([])->
io:format("init pid:~p~n",[self()]),
ets:new(?Ets_Users, [set,public,named_table]),
{ok,[]}.
%%register
handle_call({reigister,register_success,{{user,Name},{socket,Socket}}}, _From,Tab)->
io:format("------------------opt_chat(register)-------------------\n"),
ets:insert(?Ets_Users, {Name,Socket}),
{reply, ok, Tab};
%%login
handle_call({login,success,{{user,Name},{scoket,Socket}}}, _From,Tab)->
io:format("------------------opt_chat(login)-------------------\n"),
ets:insert(?Ets_Users, {Name,Socket}),
{reply, ok, Tab};
%%get_all_users
handle_call({get_all_users,{socket,Socket},{server_Name,Server_name}}, _From,Tab)->
io:format("------------------opt_chat(get_call)-------------------\n"),
List_ets=ets:tab2list(?Ets_Users),
List_name=get_name_list(List_ets,[]),
Info={get_all_users,List_name,{socket,Socket}},
gen_server:cast({Server_name,?Node_Node}, Info),
{reply, ok, Tab};
%%chat_room
handle_call({chat,{name,Name},{content,Msg},{server_Name,Server_name}}, _From,Tab)->
io:format("------------------opt_chat(chat_room)-------------------\n"),
List_ets=ets:tab2list(?Ets_Users),
List=lists:keydelete(Name, 1, List_ets),
Request_node={chat,{name,Name},{content,Msg},List},
gen_server:cast({Server_name,?Node_Node}, Request_node),
io:format("to_all_person:~p~n", [List]),
{reply, ok, Tab};
%%create group
handle_call({chat_group,{name,Name},{list,List},{msg,Content},{server_Name,Server_name}}, _From,Tab)->
io:format("------------------opt_chat(chat_group)-------------------\n"),
List_has_chekt=check_gr(List,[],[]),
{{in,List_node},{no,List_node_no}}=List_has_chekt,
Request_node={chat_gr,{name,Name},{content,Content},List_node},
gen_server:cast({Server_name,?Node_Node}, Request_node),
io:format("to_group_in:~p~n", [List_node]),
io:format("to_group_not:~p~n", [List_node_no]),
%% gen_server:call({?Server_Node,?Node_Node}, Request_node),
{reply, ok, Tab};
%%quite
handle_call({quite,{socket,Socket},{server_name,_Server_name}}, _From,Tab)->
io:format("------------------opt_chat(quite)-------------------\n"),
%% List_ets=ets:tab2list(?Ets_Users),
%% List_name=get_name_list(List_ets,[]),
%% Info={get_all_users,List_name,{socket,Socket}},
%% io:format("info:~p~n", [Info]),
%% gen_server:cast({Server_name,?Node_Node}, Info),
List=ets:tab2list(?Ets_Users),
case lists:keysearch(Socket, 2, List) of
{value,{Name,_S}}->
ets:delete(?Ets_Users,Name),
Request_holl={quite,{name,Name}},
gen_server:call({?Server_Holl,?Node_Holl}, Request_holl);
{false}->
io:format("error in \n:
moudle: opt_chat \n
fun: handle_call({quite,{socket,Socket}}, _From,Tab)")
end,
{reply, ok, Tab};
handle_call(stop, _From, Tab) ->
{stop, normal, stopped, Tab}.
handle_cast(_Msg, State) -> {noreply, State}.
handle_info(_Info, State) -> {noreply, State}.
terminate(_Reason, _State) -> ok.
code_change(_OldVsn, State,_Extra) -> {ok, State}.
get_name_list([{Name,_Socket}|T],Acc)->
get_name_list(T, [Name|Acc]);
get_name_list([],Acc)->
lists:reverse(Acc).
%%just test check_gr
ts()->
ets:new(?Ets_Users, [set,public,named_table]),
ets:insert(?Ets_Users, {wuzhao,wudong}),
ets:insert(?Ets_Users, {conghui,wuzhao}),
ets:insert(?Ets_Users, {sim,sunny}).
check_gr([Key_name|T],Acc_in,Acc_not)->
io:format("Key_name:~p~n",[Key_name]),
case ets:lookup(?Ets_Users, Key_name) of
[{Name,Socket}]->
check_gr(T,[{Name,Socket}|Acc_in],Acc_not);
[]->
check_gr(T,Acc_in,[Key_name|Acc_not])
end;
check_gr([],Acc_in,Acc_not)->
io:format("Acc_in:~p~n", [Acc_in]),
io:format("Acc_not:~p~n", [Acc_not]),
List={{in,Acc_in},{no,Acc_not}},
List.
注意:
ets:new(?Ets_Users, [set,public,named_table]),
这个ets表,表示的是现在在线的客户端的{姓名,端口号}
问题:怎么样动态的创建节点?比如一个chat节点连接的用户太多,比如大于100个客户端的连接,就可以在代码中新开启一个chat的节点,来处理其他的客户端连接?这个在erlang中可以实现么?
客户端的代码我会打包给大家的~~
欢迎转载,请注明出处