Teilnehmer
web.sta – web basierte Applikation, Ziel-Webbrowser ist Internet Explorer der Version 9 und 11
TextSystem – eine eigenständige Desktop-Anwendung, basierend auf Java/Swing
IntermediateLayer – eine Client-Server Anwendung, die web.sta und TextSystem miteinander verbindet.
web.sta kann TextSystem über den IntermediateLayer starten. IntermediateLayer erstellt zu diesem Zweck einen HTTP-Server und web.sta sendet einfache GET- oder POST-Abfragen an den localhost. IntermediateLayer verarbeitet die Eingangsparameter und startet das TextSystem. Da keine Rückmeldung erforderlich ist, ist das Interaktionsschema einfach und robust genug.
Citrix
In einer Citrix-Umgebung ist es nicht möglich, mehrere Listening-Sockets für dieselbe IP-Adresse und denselben Port zu erstellen. Man muss entweder den Port oder die IP-Adresse ändern. Citrix bietet jedoch einen speziellen Mechanismus an, um diese Einschränkung zu umgehen, ohne den Algorithmus des Programms zu ändern. Dieser Mechanismus wird als „Virtual IP Loopback“ bezeichnet. Hier muss der Administrator einfach die erforderlichen Anwendungen im Citrix-Konfigurationsfenster konfigurieren. Die Anwendung, die „localhost“ für Socket-Verbindungen verwendet, erhält nicht 127.0.0.1, sondern eine IP-Adresse in der Form 127.0.0.<SID + 1>, wobei SID die Sitzungs-ID des Windows-Benutzers ist.
Die Problematik
Unter IE9 (und auch mit anderen Browsern) unter Windows Server 2008 R2 funktionierte dies alles einwandfrei. Dann jedoch wollte der Kunde etwas Neues und Windows Server 2012 R2 erschien mit IE11. Das ganze System hörte auf zu funktionieren. Unabhängig von den Citrix Einstellungen versucht IE11 bei Abfragen auf „localhost“ immer eine Verbindung zu 127.0.0.1 herzustellen, diese natürlich scheitert, weil auf der Adresse keiner Hörer (Listener) gibt. Nach ein wenig Recherche kamen wir zu dem Schluss, dass dies ein Bug in IE11 sein muss.
RoutingService
Wenn die Virtualisierung des „localhost“ in Citrix-Box für IE11 nicht funktioniert, schreiben wir sie selbst!
Deshalb entschlossen wir uns, selbst einen Windows-Dienst zu erstellen, der ein einfacher Webserver ist und zu 127.0.0.1 eine Verbindung aufbaut und damit alle Abfragen auf der Grundlage der Sitzungsnummer des Benutzers an den gewünschten IntermediateLayer umleiten. Wir haben keine einfache Lösung gefunden, um die SID zu ermitteln, aber in den Umgebungsvariablen haben wir sofort SESSIONNAME gefunden. Im Internet Explorer bekommen wir über ActiveX diese Umgebungsvariable und übergeben sie als Parameter in der HTTP-Abfrage weiter. Im RoutingService erhalten wir durch den Sitzungsnamen unter wtsapi32.lib die Sitzungsnummer. Dann leiten wir die HTTP-Abfrage um und senden die Antwort an den IE zurück.
Etwas ist schief gelaufen
Wir haben mit dem Testen und der Integration unseres Service begonnen. Aber nicht alles lief so reibungslos, wie wir es uns gewünscht hatten.
Wie sich herausstellte, kann der Name der Sitzung geändert werden, obwohl wir nicht verstanden haben, unter welchen Bedingungen dies geschieht. Es kam jedoch häufig vor, dass der Sitzungsname geändert wurde aber IE11 nur den Anfangswert der Umgebungsvariablen kennt und diesen Wert dauerhaft an den RoutingService weitergibt.
Was ist in der Registry?
Es war notwendig, einen anderen Weg zu finden, um den Sitzungsnamen zu ermitteln. Wir haben nach Informationen zu Sitzungen in der Registry gesucht und wurden fündig: Unter HKEY_CURRENT_USER \ Volatile Environment ist es möglich eine Liste aller Sitzungen des aktuellen Benutzers abzurufen.
Wenn es nur um eine Anmeldung geht, ist alles in Ordnung, wir können sie lesen und verwenden. Wenn es für einen Benutzer jedoch viele Sitzungen gibt, müssen wir irgendwie feststellen, in welcher Sitzung wir uns befinden. Die beste Möglichkeit die uns einfiel war, den Pfad zum Ordner mit den temporären Dateien abzugleichen.
Beispiel:
Im IE erhalten wir den aktuellen Pfad zu TEMP mithilfe von ActiveX Scripting.FileSystemObject. Auf diese Weise konnten wir den Namen unserer Sitzung ermitteln. Aber das ist nicht alles. Der Wert der Schlüssel in der Volatile Environment ist in der Tat die SID. Somit können wir sofort die erforderliche IP-Adresse in JavaScript abrufen und eine Anfrage an diese senden.
Sollen wir es vereinfachen?
Schließlich können wir die SID abrufen und direkt eine Verbindung herstellen, ohne den RoutingService zu verwenden. Aber der Lösungsweg sieht immer noch nicht schön aus. Die Internetsuche hat gezeigt, dass das Problem besteht, aber wie es behoben werden kann wird nirgendwo beschrieben. Und auch Microsoft bietet dazu bisher keine Lösung.
Wir hoffen, dass jemand mit diesem spezifischen Problem von unserer Erfahrung profitieren kann.