Before we get to more details on sending messages, we need to talk a little more about signing out.  Technically, when I had the application sign out using BeginTerminate, this wasn’t entirely correct.  For those of you who have examined the SipEndpoint class, you may have noticed that there are two methods – Terminate and Unregister.

 

Terminate actually closes any signaling sessions in use by that endpoint.  After Terminate is called, we cannot use our SipEndpoint object any longer.  One important note here is that Terminate does not send any message to the Microsoft Office Communications server.  After calling Terminate, however, any attempts to communicate with our endpoint will be unsuccessful.

 

Unregister is actually the opposite of Register.  While Register tells the server “Hey! I’m here!”, Unregister tells the server “I’m no longer here.”.  So, to be proper in this case we should use both.  If we are not communicating with a server (which later we will see is the case with SipPeerToPeerEndpoint) then we do not need to call Register and UnRegister.

 

First we will modify our client.  Our sign out logic is now a bit more complicated.  First, we need to change our Terminate method in the manager.  If we do not have a session, instead of calling BeginTerminate on the endpoint we will call BeginUnregister.

 

public void Terminate()

{

    // TODO: there are threading issues with this code

    if (null != _session)

    {

        _session.BeginTerminate(new AsyncCallback(SessionTerminateCallback), _session);

    }

    else

    {

        // Unregister the endpoint

        _endPoint.BeginUnregister(new AsyncCallback(UnregisterCallback), _endPoint);

    }

}

 

The callback for Unregister then calls BeginTerminate on the endpoint.

 

/// <summary>

/// Callback when the unregister is complete

/// </summary>

/// <param name="asyncResult"></param>

private void UnregisterCallback(IAsyncResult asyncResult)

{

    SipEndpoint endpoint = asyncResult.AsyncState as SipEndpoint;

 

    try

    {

        endpoint.EndUnregister(asyncResult);

        _endPoint.BeginTerminate(new AsyncCallback(TerminateCallback), _endPoint);

      RecordProgress("Endpoint unregistered");

    }

    catch (Exception)

    {

        Error("An exception occurred when unregistering the session.\n{0}", endpoint.ToString());

    }

}

 

Finally, in the callback for the session being terminated we need to call BeginUnregister on the endpoint instead of BeginTerminate.

 

private void SessionTerminateCallback(IAsyncResult asyncResult)

{

    SignalingSession session = asyncResult as SignalingSession;

 

    try

    {

        _session.EndTerminate(asyncResult);

 

        // Unregister the endpoint

        _endPoint.BeginUnregister(new AsyncCallback(UnregisterCallback), _endPoint);

        RecordProgress("Session terminated.");

    }

    catch (Exception e)

    {

        Error("An exception occurred when terminating the session.\n{0}", e.ToString());

    }

}

 

Tomorrow, before starting to learn how to send messages, we’ll cover how to determine if one party has closed the session.