funbox/smppex

Usage of functions that require session/pid

dowusu opened this issue · 4 comments

I find usage of functions such as send_pdu which takes a session/process id quite difficult; I passed the name of the module implementing the callbacks expecting it to work just as a GenServer. I was expecting the module name to be used for the process registration.

SMPPEX.ESME.start_link(ip, port, {MyModule, []})
SMPPEX.Session.send_pdu(__MODULE__, ......)

However it doesn't work, I need to explicitly pass the pid obtained from the start_link to get this function to work or I have to rely on the various callbacks to send pdus.

Am I missing something?

Hello!

to work just as a GenServer

As far as I know, GenServer does not do this by default. To get this work, one should explicitly pass name kv argument when starting the server:

{:ok, pid} = GenServer.start_link(SomeGenServerImpl, some_args, name: SomeGenServerImpl)

Many libraries make this by default in their own start_link function.

defmodule SomeGenServerImpl do
...
  def start_link() do
    GenServer.start_link(__MODULE__, [], name: __MODULE__)
  end
...
end
SomeGenServerImpl.start_link()

However, this makes difficult start many instances of SomeGenServerImpl, and, in case of SMPPEX.Session implementations, we definitely want have many sessions runnig.

Since SMPPEX.ESME.start_link does not return before session init callback returns, in your case it is safe to alias in MyModule.init function.

As far as I know, GenServer does not do this by default. To get this work, one should explicitly pass name kv argument when starting the server

Yes, GenServer doesn't do that by default; I was of the mistaken belief it was being done by the library. I was able to put together a pool of SMPPEX.Session sessions using the Registry and Supervisor; it works pretty well.

def init(_, _, opts) do
      Registry.register(EsmeRegistry, :sessions, nil)
      Kernel.send(self(), :bind)
      {:ok, opts}
  end

One thing I did notice was when I call Session.stop; Wireshark shows that an unbind request is sent from the MC which I'm unable to respond due to the closed socket. I assume this shouldn't be a problem since the socket is closed on the server.

Any recommendations on how to cleanly stop the session that involves sending an unbind request to the MC and waiting for the response before terminating.

Graceful unbind is a bit complicated because we must have functioning session to receive unbind resp.

This could be done by having an additional GenServer which manages SMPP sessions.

Since this is a commonly searched feature, there is a repo with an example %)
https://github.com/savonarola/smppex_graceful

Awesome stuff, exactly what I was looking for. I've replaced Kannel SMPP Client with this library to avoid having a lot of moving parts to manage. It works really well with no issues. Thank you.