I am developing a chat server and it is distributed. I can spawn new users (using start_link) in multiple nodes and can send a message to a node, then received message will be shown on received node. I have no idea how should I use gen_statem(FSM) for this application. I need to add a FSM between two chat users(nodes). I have used a record to save states of sender, receiver and message also. Could someone suggest me how to add gen_statem here ? I need to visualize the states received, sent respectively for send_message and receive message events.
chat server:
-module(message_server).
-behaviour(gen_server).
-export([send_message/2, receive_message/3, start_link/1, stop/0, receive_db_data/1]).
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2,
code_change/3]).
-define(SERVER, ?MODULE).
-record(message_server_state, {from, to, msgsent, msgreceived}).
%%%===================================================================
%%% Spawning and gen_server implementation
%%%===================================================================
start_link(Name) ->
gen_server:start_link({local, ?MODULE}, ?MODULE, Name, []).
init(Name) ->
io:format("~p is connected with the server...~n", [Name]),
{ok, #message_server_state{
from = node(),
to = [],
msgsent = [],
msgreceived = []
}}.
stop() ->
gen_server:stop(?MODULE).
receive_db_data(Sender) ->
database_server:getalldb(Sender).
send_message(To, Msg) ->
gen_server:call({?MODULE, node()}, {send, To, Msg}).
receive_message(Sender, To, Msg) ->
gen_server:call({?MODULE, list_to_atom(To)}, {reciv, Sender, Msg}).
handle_call({send, To, Msg}, _From, State = #message_server_state{to = Receivers, msgsent = Msgsent, from = Sender}) ->
io:format("Sent message: ~p~n", [Msg]),
receive_message(Sender, To, Msg),
{reply, ok, State#message_server_state{msgsent = [Msg | Msgsent], to = [To | Receivers]}};
handle_call({reciv, Sender, Msg}, _From, State = #message_server_state{msgreceived = Msgreceived}) ->
io:format("Sent by: ~p~n", [Sender]),
io:format("Message: ~p~n", [Msg]),
receive_db_data(Sender),
{reply, ok, State#message_server_state{msgreceived = [Msg | Msgreceived]}}.
handle_cast(_Request, State = #message_server_state{}) ->
{noreply, State}.
handle_info(_Info, State = #message_server_state{}) ->
{noreply, State}.
terminate(_Reason, _State = #message_server_state{}) ->
ok.
code_change(_OldVsn, State = #message_server_state{}, _Extra) ->
{ok, State}.