Bei der Kommunikation über das Internet gibt es so einige Hindernisse, die zu bewältigen sind. Nehmen wir in einem Beispiel an, dass ein Client einen extern angebotenen Service konsumieren will. In aller Regel wird der Server, der den Service anbietet, hinter einer Firewall stehen (z.B. Hardware- oder Softwareseitig). Hinzu kommt auch, dass die Adresse des Servers dynamisch ist und nur im lokalen Netzwerk aufgelöst werden kann (siehe Abbildung 1). Abgesehen davon, dass der Client aufgrund der dynamischen IP-Adresse den Server nicht finden kann, würde die Kommunikation spätestens an der Firewall scheitern.
Abbildung 1: Hindernisse einer Kommunikation über das Internet
Für dieses Problem gibt es nun mehrere Möglichkeiten. Die einfachste Möglichkeit ist sicherlich die, dass man die Firewall für den Client öffnet und den Server mit einem dynamischen DNS Eintrag ausstattet. Doch gerade beim Öffnen der Firewall werden viele den Kopf schütteln. Ein anderer Ansatz ist es, den Client und den Service über einen weiteren (externen) Server zu integrieren. In diesem Fall würden sich der Client und der Server zunächst zum externen Server verbinden und dieser würde als Zwischenstelle die Anfragen weiterleiten. Dieses Konzept erfordert neben den benötigten Kosten für den Betrieb auch eine Menge Zeit, um die Lösung zu realisieren. Genau an dieser Stelle setzt der Azure Service Bus an. Azure bietet bereits einen fertigen Relay-Service an, der zur Integration verschiedener Services verwendet werden kann (siehe Abbildung 2).
Abbildung 2: Azure Service Bus als Relay-Service
Bei dieser Variante verbinden sich sowohl der Client als auch der Server, der den Service anbietet, mit dem Azure Service Bus (Schritt 1 und 2) und authentifizieren sich gegen den Relay-Service. Bei diesem Schritt hält der Client und der Server jeweils eine ausgehende Verbindung offen, die als Rückkanal genutzt wird. Nachdem sich Client und Service mit dem Relay-Service verbunden haben, werden alle Anfragen des Clients (Schritt 3) direkt an den Service weitergeleitet (Schritt 4). Darüber hinaus kann auch ein so genannter hybrider-Modus verwendet werden, bei dem auf die Umleitung über die Cloud verzichtet wird, sofern sich Client und Server direkt verbinden können.
Im Folgendem wird exemplarisch ein solcher Relay Service erstellt. Hierbei wird der Client eine Nachricht an den Service schicken und dieser wird die Nachricht unverändert als Response an den Client zurücksenden.
Bevor es aber zum programmatischen Teil kommt, muss zunächst ein Azure Service Bus Namespace erstellt werden. Der Namespace kann sehr einfach über das Azure Management Portal angelegt werden (siehe Abbildung 3). Anschließend kann auch das Passwort für den angelegten Namespace in den Properties unter Default Key eingesehen werden.
Abbildung 3: Anlegen eines Service Bus Namespace
Als Nächstes erstellt man eine Visual Studio Solution mit zwei Konsolenanwendungen. Die eine Konsolenanwendung wird den Service hosten (EchoService), die andere wird den Service als Client konsumieren (EchoServiceClient). Dazu kommt noch eine Class Library für die Servicedefinition (EchoServiceContract).
Im nächsten Schritt wird der EchoService implementiert, der Service nimmt eine einfache Nachricht entgegen und leitet sie unverändert an den Client weiter (siehe Abbildung 4).
Abbildung 4: EchoService mit Implementierung
Für den gerade erstellten Service wird ein Host benötigt. Hierzu werden dem Projekt EchoService zunächst zwei Referenzen hinzugefügt: System.ServiceModel und Microsoft.ServiceBus. Die letztere Referenz ist für eine Komponente der Windows Azure AppFabric und enthält alle Definitionen der Relay-Bindings.
Als Nächstes fügt man dem Projekt eine Konfigurationsdatei hinzu, die den Endpunkt des Services definiert sich gegenüber dem Azure Service Bus authentifiziert (siehe Abbildung 5).
Abbildung 5: App.config des EchoServices
Zuletzt muss man den Host implementieren, der den Service anbieten wird. Dabei wird der zuvor erstellte Endpunkt als öffentlich sichtbar deklariert, womit die Clients auch die Möglichkeit bekommen, den Service zu konsumieren (siehe Abbildung 6).
An dieser Stelle ist der Service bereits fertig und es fehlt noch der Client, der den Service konsumiert. Analog zum EchoService fügt man dem EchoServiceClient-Projekt eine Konfigurationsdatei hinzu, mit der Außnahme, dass der Client-Endpunkt einen Namen bekommt (siehe Abbildung 7).
Abbildung 7: App.config des EchoServiceClients
Als letzter Schritt wird ein WCF-Channel deklariert, der die Echo Methode des Services mit einer Nachricht aufruft (siehe Abbildung 8).
Abbildung 8: EchoService Client
Nun können beide Konsolenanwendungen gestartet werden. Der Client sollte zunächst warten, bis der Service bereit ist. Es kann je nach Internet Verbindung bis zu 30 Sek. dauern, bis sich der Service Host mit dem Azure Service Bus verbunden hat. Nachdem der Service bereit ist, kann nun der Client über den Azure Service Bus Nachrichten an den Service senden (siehe Abbildung 9 und 10).
Abbildung 9: Nachrichtenaustausch zwischen Client und Server
Abbildung 10: Weiterleitung der Nachrichten an den Client
Mit dem Azure Service Bus ist es so einfach wie noch nie, Services zu integrieren. In der Vergangenheit war es noch erforderlich, über einen weiteren Server dieses Verhalten zu realisieren. Hierbei sind allerdings neben der benötigten Zeit für die Realisierung noch umfassende Kenntnisse über Netzwerkstandards und -programmierung notwendig. Dies erübrigt sich mit dem Azure Service Bus. Die Integration über den Service Bus weicht nur geringfügig von der Implementierung eines klassischen WCF-Services ab und für die entfernte Kommunikation müssen noch nicht einmal sicherheitskritische Öffnungen an der Firewall vorgenommen werden.