SIP-Programmierung für den Java-Entwickler

Das Session Initiation Protocol (SIP) ist ein Kontrollprotokoll (Signalisierungsprotokoll), das von der Internet Engineering Task Force (IETF) entwickelt wurde, um interaktive Multimedia-IP-Sitzungen einschließlich IP-Telefonie, Anwesenheit und Instant Messaging zu verwalten. Die SIP-Servlet-Spezifikation (Java Specification Request 116), die im Rahmen des Java Community Process entwickelt wurde, bietet ein Standard-Java-API-Programmiermodell für die Bereitstellung von SIP-basierten Diensten. SIP Servlet basiert auf der beliebten Java-Servlet-Architektur der Java Platform Enterprise Edition (Java EE ist Suns neuer Name für J2EE) und bietet SIP-Lösungen Funktionen zur Entwicklung von Internetanwendungen.

IT und Telekommunikation laufen zusammen. Netzwerk-IT-Anwendungen, die normalerweise datenorientiert sind, werden mit Kommunikationsanwendungen zusammengeführt. Die zunehmende Anzahl von Call Me-Schaltflächen auf Webseiten ist ein Beispiel für diese Integration. Die SIP-Servlet-Spezifikation bietet Java-Entwicklern ein bekanntes Programmiermodell zum Erstellen konvergierter Anwendungen. Dieser Artikel enthält eine schrittweise Einführung in die Verwendung des SIP-Servlets zum Erstellen eines einfachen Echo-Chat-Dienstes.

Gesprächs Protokoll

In der Anforderung von Kommentaren 3261 definiert, ist SIP ein Protokoll zum Einrichten, Ändern und Beenden von Multimedia-IP-Kommunikationssitzungen. Abbildung 1 ist ein einfaches Beispiel für die Verwendung von SIP zum Einrichten eines VoIP-Anrufs (Voice-over-Internet Protocol):

Alle weißen Linien in Abbildung 1 repräsentieren die SIP-Kommunikation. Der Anrufer sendet eine SIP INVITE-Anfrage, um den "Angerufenen" zum Einrichten einer Sprachsitzung einzuladen. Callee antwortet zuerst mit einer Nachricht mit dem Statuscode 180, um anzuzeigen, dass das Telefon klingelt. Sobald das Telefon abgenommen wird, wird eine Antwort mit einem Statuscode von 200 an den Anrufer gesendet, um die Einladung anzunehmen. Der Anrufer bestätigt dies mit einer ACK-Nachricht, und die Sitzung wird eingerichtet. Sobald die Sitzung eingerichtet ist, wird die tatsächliche digitalisierte Sprachkonversation normalerweise über das Realtime Transmission Protocol (RTP) mit der Sitzung übertragen, wie die rote Linie in Abbildung 1 zeigt. Wenn die Konversation endet, wird eine SIP BYE-Anforderung gesendet, gefolgt von einer Antwort mit einem 200-Statuscode, um die Beendigung der Sitzung zu bestätigen.

Hier ist ein Beispiel für eine SIP INVITE-Anforderung und eine Antwort mit einem 200 OK-Statuscode:

SIP INVITE request: INVITE sip:[email protected] SIP/2.0 Via: SIP/2.0/UDP pc.caller.com;branch=z9hG4bK776asdhds Max-Forwards: 70 To: Callee From: Caller ;tag=1928301774 Call-ID: a84b4c76e66710 CSeq: 314159 INVITE Contact: Content-Type: application/sdp Content-Length: 142

(content (SDP) is not shown)

SIP 200 OK Antwort:

SIP/2.0 200 OK Via: SIP/2.0/UDP pc.caller.com;branch=z9hG4bK776asdhds;received=192.0.2.1 To: Callee ;tag=a6c85cf From: Caller ;tag=1928301774 Call-ID: a84b4c76e66710 CSeq: 314159 INVITE Contact: Content-Type: application/sdp Content-Length: 131

(content (SDP) is not shown)

Wie Sie sehen können, ähnelt das Format von SIP HTTP. Im Vergleich zu HTTP ist SIP jedoch:

  • Verantwortlich für das Sitzungsmanagement. Der eigentliche Multimedia-Inhalt wie Sofortnachrichten, Sprache und Video kann über SIP übertragen werden oder nicht.
  • Asynchron und zustandsbehaftet. Für jede SIP-Anfrage können mehrere Antworten vorliegen. Dies bedeutet, dass die Anwendung jede SIP-Nachricht in einem geeigneten Statuskontext verarbeiten muss.
  • Ein Anwendungsprotokoll, das sowohl auf zuverlässigen als auch auf unzuverlässigen Transporten ausgeführt werden kann. Daher muss die Anwendung die Nachrichtenübermittlung mit erneuter Übertragung und Bestätigung der Nachricht garantieren.
  • Ein Peer-to-Peer-Protokoll, bei dem keine klare Unterscheidung zwischen Client und Server besteht. Jede Seite muss in der Lage sein, Anfragen und Antworten zu senden und zu empfangen.

SIP-basierte Dienste

SIP-basierte Dienste sind SIP-Server, die Dienste wie Nachrichtenrouting für SIP-Endpunkte wie IP-Telefone anbieten. In Abbildung 2 bieten beispielsweise der SIP-Registrar-Server und der Proxy-Server SIP-Registrierungs- und Proxy-Dienste an, um die SIP-Endpunkte beim Auffinden und Kommunizieren zu unterstützen.

Abbildung 2 zeigt Folgendes:

  1. Callee registriert sich beim Registrar-Server, indem er eine REGISTER-Anfrage sendet.
  2. Der Registrar-Server akzeptiert die Registrierung, die die Namensadresse des Angerufenen enthält, indem er mit einem Statuscode von 200 OK antwortet.
  3. Anruferanfragen zum Einrichten einer Kommunikationssitzung mit Angerufenen durch Senden einer INVITE-Anfrage an den Proxyserver. Der Inhalt der INVITE-Nachricht enthält normalerweise die Beschreibung der Kommunikationssitzung, die der Anrufer einrichten möchte, z. B. Medientyp, Sicherheit oder IP-Adresse. Die Beschreibung ist normalerweise im SDP-Format (Session Description Protocol).
  4. Der Proxyserver sucht auf dem Registrar-Server nach der aktuellen Adresse des Angerufenen. Beachten Sie, dass die Suche ein Implementierungsproblem ist, das nicht Teil von SIP ist.
  5. Der Proxyserver leitet die INVITE-Anfrage basierend auf seiner aktuellen Adresse vom Anrufer an den Angerufenen weiter.
  6. Callee nimmt die Einladung an, indem er mit einem Statuscode von 200 OK antwortet. Die 200 OK-Antwort auf eine INVITE-Anfrage enthält normalerweise die Beschreibung der Kommunikationssitzung, die der Angerufene mit dem Anrufer einrichten kann.
  7. Der Proxyserver leitet eine 200-OK-Antwort vom Angerufenen an den Anrufer weiter.
  8. Der Anrufer bestätigt den Sitzungsaufbau, indem er eine ACK-Nachricht an den Proxyserver sendet. Die ACK-Nachricht kann die endgültige Vereinbarung über die Sitzung enthalten.
  9. Der Proxyserver leitet die ACK wiederum an den Angerufenen weiter. Somit wird der Drei-Wege-Handshake über den Proxyserver abgeschlossen und eine Sitzung eingerichtet.
  10. Jetzt erfolgt die Kommunikation zwischen Anrufer und Angerufenen. Das für die Kommunikation verwendete Protokoll kann SIP sein oder nicht. Beispielsweise können Sofortnachrichten über SIP übertragen werden. Sprachgespräche werden normalerweise über RTP übertragen.
  11. Jetzt beendet der Angerufene das Gespräch und möchte die Sitzung durch Senden einer BYE-Anfrage beenden.
  12. Der Anrufer antwortet mit einem Statuscode von 200 OK, um die Beendigung der Sitzung zu akzeptieren.

Im obigen Szenario leitet der SIP-Proxyserver die Nachrichten einfach an die aktuelle Adresse des Angerufenen weiter. Wie Sie sich vorstellen können, können interessantere und intelligentere Routing-Dienste stattfinden. Beispielsweise kann der Proxyserver einem Benutzer "folgen", indem er die Nachrichten an einen erreichbaren Ort weiterleitet, z. B. an ein Mobiltelefon, selbst wenn jemand auf seinem Bürotelefon anruft.

SIP-Servlet

Die in Java Specification Request 116 definierte SIP-Servlet-Spezifikation bietet ein Container-Servlet-Programmiermodell für SIP-Anwendungen. Da JSR 116 von der Java-Servlet-Architektur in Java EE abgeleitet ist, bietet es Java EE-Entwicklern einen vertrauten Ansatz zum Erstellen von SIP-Diensten.

Die folgende Tabelle fasst die Ähnlichkeit zwischen HTTPServletund zusammen SIPServlet.

Vergleich zwischen einem HTTP- und einem SIP-Servlet

  HTTP SCHLUCK
Servlet-Klasse HttpServlet SipServlet
Session HttpSession SipSession
Anwendungspaket KRIEG SAR
Bereitstellungsdeskriptor web.xml sip.xml

Ähnlich wie HTTP-Servlets erweitern SIP-Servlets die javax.servlet.sip.SipServletKlasse, wodurch wiederum die javax.servlet.GenericServletKlasse erweitert wird. SipServletÜberschreibt, wie Sie vielleicht vermutet haben, die service(ServletRequest request, ServletResponse response)Methode zur Verarbeitung verschiedener Arten von SIP-Nachrichten.

Since SIP is asynchronous, only one of the request and response arguments in the service() method is valid; the other one is null. For example, if the incoming SIP message is a request, only the request is valid and the response is null, and vice versa. The default implementation of the SipServlet class dispatches requests to doXXX() methods and responses to doXXXResponse() methods with a single argument. For example, doInvite(SipServletRequest request) for a SIP invite request and doSuccessResponse(SipServletResponse response) for SIP 2xx class responses. Typically SIP servlets override doXXX() methods and/or doXXXResponse() methods to provide application logic.

How do you send SIP responses if there is no response object in the doXXX() methods? In SIP servlets, you must call one of the createResponse() methods in the javax.servlet.sip.SipServletRequest class to create a response object. Then, call the send() method on the response object to send the response.

How about creating a SIP request in a SIP servlet? There are two ways to create SIP requests: Call either one of the createRequest() methods on the SipSession class to create a SIP request within the session, or one of the createRequest() methods on javax.servlet.sip.SipFactory to create a SIP request within a new SipSession. To get an instance of SipFactory, you must call getAttribute("javax.servlet.sip.SipFactory") on the ServletContext class.

The SipFactory is a factory interface in the SIP Servlet API for creating various API abstractions, such as requests, address objects, and application sessions. One interesting object created by SipFactory is javax.servlet.sip.SipApplicationSession. The intention of JSR 116 is to create a unified servlet container that can run both an HTTP and a SIP servlet. SipApplicationSession provides a protocol-agnostic session object to store application data and correlate protocol-specific sessions, such as SipSession and HttpSession. Hopefully this concept will be adopted by future versions of the Servlet API to make it javax.servlet.ApplicationSession instead of javax.servlet.sip.SipApplicationSession.

The SipApplicationSession manages protocol-specific sessions like SipSession. The SipSession interface represents the point-to-point relationship between two SIP endpoints and roughly corresponds to a SIP dialog defined in Request for Comments 3261. SipSession is inherently more complicated than its HTTP counterpart due to SIP's asynchronous and unreliable nature mentioned above. For example, Figure 3 shows the SipSession state transitions defined in JSR 116:

Typically, an HttpSession is created when a user logs in and destroyed after logout. A SipSession typically represents one logical conversation, even if you have multiple conversations between the same endpoints. So SipSession is more dynamic and has a shorter lifespan.

Weitergehende Diskussionen über den SipSessionLebenszyklus und seine Beziehung zum SIP-Dialog gehen über den Rahmen dieses Artikels hinaus. Glücklicherweise übernimmt der Container den größten Teil der Komplexität, wie z. B. Lebenszyklus- und Statusübergänge, und SipSessionkann einfach als Speicher für Sitzungsdaten verwendet werden.

Ein vollständiges Beispiel: EchoServlet

Das EchoServlet ist ein SIP-Servlet, das die in Windows Messenger eingegebenen Sofortnachrichten wiedergeben kann: