The pid which is returned I want to use that pid in check_online function. But the pid which is returned is a tuple {:ok, pid}. So that’s why I’m passing a variable in check_online function “a”. Is this approach correct ?
The last line of the init will set the state and the pid will now come in as part of that state in handle_call. You can extract the pid using pattern matching:
def handle_call(:check_online, _from, %{pid: pid} = state) do
...
end
Thanks. I did this as you suggested. But I’m getting an error
def start_link(xmpp_config) do
GenServer.start_link(__MODULE__, xmpp_config, name: @name)
end
def init(xmpp_config) do
opts = [jid: xmpp_config[:jid], password: xmpp_config[:password]]
{:ok, pid} = Conn.start_link(opts)
{:ok, %{pid: pid, user_name: xmpp_config[:user_name], rooms: []}}
end
def check_online(a) do
GenServer.call(a, :check_online)
end
def handle_call(:check_online, _from, %{pid: pid} = state) do
{:ok, check} = Conn.send(pid, Stanza.presence)
{:reply, check, state}
end
[error] GenServer ChatApiWeb.Client terminating
** (MatchError) no match of right hand side value: :ok
(chat_api 0.1.0) lib/chat_api_web/channels/client.ex:24: ChatApiWeb.Client.handle_call/3
(stdlib 3.12.1) gen_server.erl:661: :gen_server.try_handle_call/4
(stdlib 3.12.1) gen_server.erl:690: :gen_server.handle_msg/6
(stdlib 3.12.1) proc_lib.erl:249: :proc_lib.init_p_do_apply/3
Last message (from #PID<0.1128.0>): :check_online
** (EXIT from #PID<0.1128.0>) shell process exited with reason: an exception was raised:
** (MatchError) no match of right hand side value: :ok
(chat_api 0.1.0) lib/chat_api_web/channels/client.ex:24: ChatApiWeb.Client.handle_call/3
(stdlib 3.12.1) gen_server.erl:661: :gen_server.try_handle_call/4
(stdlib 3.12.1) gen_server.erl:690: :gen_server.handle_msg/6
(stdlib 3.12.1) proc_lib.erl:249: :proc_lib.init_p_do_apply/3
Is this related to handle_call function where I’ve set the {:ok, check} because according to the library I have to do this
Sorry, I’m really trying here, but I’m struggling to understand your question.
The def start_link(xmpp_config) is a defintion you have given. I’m not clear what you mean when you say “it expects” a variable. It only expects it because you’ve said it should be expected in this definition.
What I think you’re trying to do here is define a worker. Your application likely has a Supervisor and you’re defining this as one of the workers it needs to start (this is normally defined in the file application.ex). You can tell the Supervisor what initial arguments to pass into the start_link method (refer to this https://hexdocs.pm/elixir/Supervisor.Spec.html#worker/3).
So the steps look like this:
Your worker is started, presumably passing in xmpp_config as an argument. The supervisor kicks off the process of staring your worker calling your start_link method.
Now within this method, you call GenServer.start_link. Here you’re telling it to to call the init method of the same module (the fact that you wrote __MODULE__ tells it you want it to call init within this same module). Since you are using xmpp_config as the second argument to GenServer.start_link it knows to pass this as the argument to init.
Now we enter your init function. You’re defining the opts on the first line. On the second line you’re calling Conn.start_link which is defined by that Romeo package.
Romeo returns a tuple containing {:ok} and the pid.
As the last step, you’re telling init to return {:ok, %{pid: pid, user_name: xmpp_config[:user_name], rooms: []}}. Whatever is returned from init will be the initial state.