/client

Reconnecting

Setting up reconnect

Simple and elegant way to perform reconnect is setting up a timer, which checks periodically state of the connection and reacts in case the connection is lost. Timer events are safer because they are system maintained thus usually do not interfere with multithreading that is done by the library.

Complete source code

Source code used in this chapter is extracted from Windows Service Example in C# complete source code for Microsoft Visual Studio 2008+ which is included in samples contained within archive/installation package.

Please review the example for more detailed comments and details which were removed here to better focus on crucial parts of the solution.

In the example below timer is System.Timers.Timer class object with it's AutoReset property set to false. Then in a place where the application is initialized timer is started for it's first lap:


protected override void OnStart(string[] args)
{
  // [...]

  // Signal for automatic reconnecting that
  // service initialization is finished
  bServiceReady = true;

  // Start timer for first lap
  TimerReconnect.Enabled = true;
}

Actually reconnecting

Once timer fires it's Elapsed event then the following code is executed:


private void TimerReconnect_Elapsed(object sender,
  System.Timers.ElapsedEventArgs e)
{
  if (bServiceReady && !bConnected) {

    // Connect to the SMSC
    int result = clientSMPP.tcpConnect("localhost", 2345, "");

    if (result != 0) {
      // Failed to connect with the SMSC
    } else {
      // Initialize session
      result = clientSMPP.smppInitializeSession(
        "id", "password", 1, 1, "123456");

      if (result != 0) {
        // Failed to initialize session with SMSC
      } else {
        // Connected & initialized properly
        bConnected = true;
      }
    }
  }

  // Retrigger the reconnect timer
  TimerReconnect.Enabled = true;
}

There are two important boolean flags to consider bServiceReady and bConnected.

First of them signals application is ready to service connections. It should be set to true after everything that is needed is properly initialized and set to false before the application's shutdown, when the connections should not be restored anymore. In Windows Service application such a place is typically between OnStart and OnStop methods.

Second variable bConnected monitors connection state. It is set to true after the connection has been properly established and initialized and set to false inside OnTcpDisconnected event:


private void clientSMPP_OnTcpDisconnected(object sender,
  smscc.tcpDisconnectedEventArgs e)
{
  bConnected = false;

  // [...]
}

It is also important that in the approach proposed at the very end of the Elapsed event code timer has to be retriggered for another lap. This is because timer has AutoReset property set to false and it allows to avoid having another event triggered when reconnect procedure takes longer than timespan between events which may happen e.g. because of lengthy DNS lookups, network issues etc.

Shutting down

Finally, when automatic reconnect has to be stopped:


protected override void OnStop()
{
  // Signal for automatic reconnecting that
  // service shutdown has been started
  bServiceReady = false;

  // Stop reconnecting
  TimerReconnect.Enabled = false;

  // Disconnect from the SMSC
  clientSMPP.tcpDisconnect();

  // [...]
}

Conclusion

What seems elegant about this approach is that there is only one place where the connection is actually created and initialized. Both connecting an reconnecting happens in the same timer event.

Inside OnTcpDisconnected event

Another, maybe even more intuitive method, formerly disallowed but from version 7 of the library perfectly legitimate is to make reconnect inside the code of the library's OnTcpDisconnected event. Formerly calling tcpConnect from inside the event would result in an error. It was pointed out that it may be necessary e.g. in the case of often dropped connections to retry reconnect in fastest way possible. It has been altered and now reconnect procedure can be initiated directly from the code of OnTcpDisconnected event.

It requires however emphasizing that this method performs only one reconnect and if the SMSC would be unreachable at this time some other method with a repetitive attempts is necessary. So in turn similar to above depicted routine is required, just started for the first time from the event's code.

Why there is no automatic reconnect built in?

There is no automatic reconnect among functionality offered by the library. Decision not to implement it was conscious and is supported by a vast set of arguments.

Reconnecting is at least two step process which consists of establishing connection on TCP/IP level first and initialization on SMSC protocol level as a second step. Implementing reconnect would join and hide these two steps inside library thus hiding results, as error codes, returned by particular operations. It would also remove certain flexibility. One can imagine different ways of reestablishing connection in custom applications e.g. reconnect synchronized with different events, different reaction on errors on various steps of reconnect process etc.

See Also

Usage Overview