I have a gen server that receives a message On a TCP connection. To demonstrate what I want I have an erlang process running where I’m listening on a port and receive a message from the other erlang process.
Elrang part receiver
2> {ok, LSocket} = gen_tcp:listen(1200, [binary, {active, true}]).
{ok,#Port<0.5>}
3> {ok, ASocket} = gen_tcp:accept(LSocket)
3> .
{ok,#Port<0.6>}
4> flush().
Shell got {tcp,#Port<0.6>,<<"Heleleeeeee">>}
ok
I want to wrap this in a gen server process. So I have written a code something like this
def start(), do: GenServer.start_link(__MODULE__, [], name: __MODULE__)
def get(), do: GenServer.cast(__MODULE__, {:get})
#callbacks
def init([]) do
{:ok, socket} = GenTCP.listen(@port, @tcp_options)
:ok = Inet.setopts(socket, active: :once)
{:ok, %State{socket: socket}}
end
def handle_cast({:get}, %State{socket: socket} = state) do
{:ok, conn} = GenTCP.accept(socket)
# case GenTCP.recv(conn, 0) do
# {}
# end
{:noreply, state}
end
def gen_tcp_accept(socket) do
GenTCP.accept(socket)
end
how can I do something similar here and receive a message and use the message to respond back to what kind of msg I have got?
Nicd
April 25, 2022, 7:55am
2
Arbitrary messages are delivered to genservers using the handle_info
callback: GenServer — Elixir v1.13.4
This sounds like you handle a call
not a cast. You can return {:noreply, state}
from handle_call
and respond at a later time using GenServer.reply
if you keep arount the from
(second parameter) received in handle_call
.
can we inspect the message that we’ve received in handle info?
suppose if I want to pattern match on this Shell got {tcp,#Port<0.6>,<<"Heleleeeeee">>}
and extract the message from it.
Nicd
April 25, 2022, 12:07pm
5
Yes, just like in handle_cast
and handle_call
. handle_info
receives the message as the first argument and the state as the second.
I added this
def handle_info(msg, %State{socket: socket} = state) do
Logger.info(msg, "sdasds")
{:noreply, state}
end
But I’m not getting any msg. I tried Logger also
msg
is not necessarily a string (rather unlikely I’d even say) so are your sure it’s not just crashing?
msg will be this
{tcp,#Port<0.6>,<<“Heleleeeeee”>>}
so it should be something like this
def handle_info({:tcp, socket, data}, %State{socket: socket} = state) do
IO.inspect(data)
{:noreply, state}
end
But inspect is not returning any value. It does not reach handle_info
I’d use active: false
for a simple gen_tcp server and ranch for the more complex cases.