The type of endpoint to use in a peer-to-peer application that does not require registration with a SIP registration server is a SipPeerToPeerEndpoint instance. The SipPeerToPeerEndpoint class derives from the RealTimeEndpoint type, which is an abstract class.

Creating a SipPeerToPeerEndpoint Instance

An application can specify explicitly the endpoint configuration as shown in the following code example. In this call to the constructor, the arguments represent, respectively, the URI for the endpoint, the server connection manager, the type of transport (TLS in this case, which is the preferred transport type), the proxy host, and the port for the proxy host.

Copy Code
string certificateIssuerName = ... // Assumed to be initialized elsewhere
byte[] certificateSerialNumber = ... // Assumed to be initialized elsewhere
  RealTimeServerTlsConnectionManager serverConnectionManager = new RealTimeServerTlsConnectionManager(certificateIssuerName, certificateSerialNumber);
catch (TlsFailureException)
  // Handle exception
  // The TlsFailureReason property on TlsFailureException 
  // can be used to determine more information about the
  // failure, such as LocalCertificateNotFound,
  // UntrustedRemoteCertificate, CertificateExpired,
  // and so on.
SipPeerToPeerEndpoint endpoint = 
	new SipPeerToPeerEndpoint("",

An application typically subscribes to events that are raised by this endpoint. The following code example shows event handlers being registered for the StateChanged and MessageReceived events, as well as skeleton handlers for these events.

Copy Code
endpoint.StateChanged += new EventHandler<EndpointStateChangedEventArgs>(endpoint_StateChanged);
endpoint.MessageReceived += new EventHandler<MessageReceivedEventArgs>(endpoint_MessageReceived);

void endpoint_StateChanged(object sender, EndpointStateChangedEventArgs e)
  // Handle StateChanged events

void endpoint_MessageReceived(object sender, MessageReceivedEventArgs e)
  // Handle MessageReceived events

Inbound and Outbound Application

For an application that uses a SipPeerToPeerEndpoint to send and receive messages, create a SipPeerToPeerEndpoint instance and then use the ConnectionManager property on the SipPeerToPeerEndpoint instance to call StartListening. In the call to StartListening, pass an IPEndpoint instance. The IPEndpoint instance should have its IPAddress and Port properties set appropriately. If Port is set to 0, the stack will choose an arbitrary port. If IPAddress is set to IPAddress.Any, all addresses are listened for.

There are several constructors for SipPeerToPeerEndpoint. When you use a constructor that has a proxy server parameter, the proxy server is used for outbound traffic. Inbound traffic can occur in separate incoming connections, provided that you have indicated (by the call to StartListening) that you want the endpoint to listen for incoming messages. Without the call to StartListening, the server cannot connect to the endpoint for inbound traffic.

Inbound-Only Application

One special case of a peer-to-peer application is one that receives requests but does not send them. Such an application has no need for an outbound SIP proxy server, but does need to listen on a TCP or TLS port on the RealTimeServerConnectionManager associated with a SipPeerToPeerEndpoint for the application. For security reasons, it is recommended that deployed applications use the TLS transport type with client authentication, and with NeedMutualTls set on the server connection manager.

Outbound-Only Application

Another special case of a peer-to-peer application is one that sends requests but does not receive them. This type of application does not have to listen for incoming messages and typically sends out messages using an outbound SIP proxy server.

An outbound-only application sends all requests through the outbound SIP proxy server. This means that all connections are established with the outbound SIP proxy server. For security reasons, it is recommended that the outbound SIP proxy server be trusted and that the TLS transport type be used.

An application that does not use a SIP outbound proxy server can send requests over a connection that is established ad hoc. In this case the remote tuple is determined when the Request-URI (as a RealTimeAddress supplied in a subscription, signaling, or other session) is parsed.