Glengamoi (Forum) · AspHeute · .NET Heute (RSS-Suche) · AspxFiles (Wiki) · .NET Blogs

Remote Scripting (I)

Geschrieben von: Christian Strauch
Kategorie: ASP Tricks

This printed page brought to you by AlphaSierraPapa

"ASP ist eine Technologie, die es dem Webseitenentwickler erlaubt, seine Werke so aktiv wie möglich bei höchstmöglicher Skalierbarkeit und Performance zu halten."

Das ist eine von vielen möglichen Definitionen für Active Server Pages, die ein Freund derselben kurz mit dem Kopf nickend akzeptieren könnte, soferne er sich intensiver mit dem Kontext als mit diesem Satz beschäftigt. Steht die Aussage - so wie hier - alleine, kann sie einem erfahrenen Entwickler schon Bauchschmerzen bereiten. Der angesprochene erfahrene Entwickler weiß um die Probleme, die schon - auf unterer Schicht - das HTTP-Protokoll mit sich bringt und mit denen sich, als logische Konsequenz, jeder Webserver und mit ihm der Entwickler beschäftigen muß.

Eines der Hauptprobleme entsteht bei der Übermittlung von Client-seitig eingegebenen oder ausgelösten Daten an den Server, bzw. an die ASP Seite, die dort liegt. Umgekehrt tritt eine Variante des Problems auf, sobald auf dem Server neue Daten entstehen, während der Benutzer sich die "alten" Daten einer ASP Seite oder gar eine statisch generierte HTML-Seite ansieht.

Die Lücke zwischen Client und Server

Auf einer Webseite soll in einem Textfeld angezeigt werden, wie viele andere Benutzer sich gerade auf der aktuellen Seite befinden.

Über ASP gibt es folgende Möglichkeit, an die Problemstellung heranzugehen (1.asp):

<%@ LANGUAGE=VBScript %>
<% Option Explicit %>
<% 
Application("AnzahlNutzerAufSeite") = Application("AnzahlNutzerAufSeite") + 1 
%>
<html>
<body>
<input type="text" value="<% = Application("AnzahlNutzerAufSeite") %>">
</body>
</html>

Natürlich kann das keine Lösung sein: Der Zähler für die Anzahl der Benutzer auf der Seite wird nur erhöht, aber nicht verringert.

Was aber viel interessanter ist - während sich ein Benutzer auf der Seite befindet, kann der Zähler selbstverständlich nicht aktualisiert werden - er wird nur beim Aufbauen der Seite eingetragen. Letzteres ist nicht ohne Performance-problematische und als provisorisch einzustufende Umwege lösbar, da das HTTP-Protokoll nur dafür vorgesehen ist, simple Inhalte vom Client anfordern zu lassen oder zum Client zu übermitteln. Ist der Übermittlungsvorgang des Seitenquelltextes abgeschlossen, wird die HTTP-Verbindung beendet und läßt keine weiteren Informationen zu der angeforderten Seite mehr zu.

Genau diese Lücke wird durch eine interessante Microsoft-Technologie überbrückt: Remote Scripting.

Pseudo-States

Ich hatte gerade eben angesprochen, daß HTTP-Verbindungen nach der Anforderung und dem Erhalt von Informationen sofort beendet werden. Da mit dieser Tatsache der momentane "Zustand" des Benutzers auf der Seite nicht übermittelt werden kann, wird das HTTP-Protokoll "stateless" genannt. Mit Remote Scripting ist es möglich, einen sogenannten "Pseudo-State" einzuführen, indem zwar die HTTP-Verbindung nicht offen bleibt, Daten aber trotzdem vom Client zum Server und zurück übermittelt werden können, ohne eine neue Seite anzeigen zu müssen.

Mit Remote Scripting ist es möglich, serverseitige ASP-Funktionen innerhalb einer ausgelagerten ASP Seite vom Client aus auszuführen, und die Rückgabewerte ohne erneutes Laden der Seite clientseitig per JavaScript zu benutzen. Remote Scripting verwendet dafür drei Komponenten, die als drei verschiedene Dateien vorliegen:

Das Herzstück der Remote Scripting-Technologie ist das Java-Applet rsproxy.class. Dieses Java-Applet muß weder vom Anwender noch vom Programmierer direkt angesprochen werden, denn sowohl den Code zur Benutzung als auch zur Instanzierung des Applets liefert die Datei RS.HTM. Sie wird Client-seitig durch das src-Attribut des HTML-script-Tags eingebunden.

In der RS.ASP, an der keine weiteren Veränderungen vorgenommen werden müssen, befinden sich die nötigen Funktionen, die direkte Prozeduraufrufe in der selbst erstellten ASP ermöglichen. Dabei werden Prozedurname, Parameter, etc. über die Request.QueryString-Collection übergeben und dort ausgelesen. Ein kleiner Hinweis: alle Funktionen in RS.ASP sind in JScript programmiert.

Um auf die erwünschte Funktionsbibliothek zugreifen zu können, müssen daher alle zur Verfügung gestellten Funktionen "exposed" werden. Der Entwickler muß eine sogenannte "public description" erstellen. Im Code sieht das so aus (2.ASP):

<%@ LANGUAGE=VBScript %>
<% Option Explicit %>
<!--#INCLUDE FILE="_ScriptLibrary/RS.ASP"-->

<SCRIPT LANGUAGE=Jscript RUNAT=SERVER>
RSDispatch();

function MeineServerMethoden() 
{
    this.MeineFunktion = return MyFunction();
    // oder für VBScript-Funktionen:
    this.MeineVBFunktion = Function("return MyVBFunction");
}
var public_description = new MeineServerMethoden();

function MyFunction() 
{
    return "Der Rückgabewert meiner Jscript-Funktion";
}
</SCRIPT>

<%
    Function MyVBFunction()
        MyVBFunction = "Der Rückgabewert meiner " & _
                    "VBScript-Funktion";
    End Function
%>

Der Aufruf von RSDispatch() initialisiert hierbei die Übergabe der aufzurufenden Methode und aller Parameter.

Das Verfahren der exposed methods ist hier durch die Instanzierung der selbstgeschriebenen Funktion MeineServerMethoden() als Objekt ersichtlich. Dadurch können die dem Client zur Verfügung gestellten Funktionen über JScript angesprochen werden.

Es stellt sich die Frage, warum Microsoft hierbei auf JScript und nicht auf VBScript zurückgreift. Eine der möglichen Antworten ist sicherlich, dass es in VBScript keine Möglichkeit gibt, einen String als Anweisung auszuwerten. Wird der oben skizzierten ASP nun als QueryString der Methodenname der aufzurufenden Funktion übergeben, so geschieht das als String - die aufgerufene ASP muß diesen String so konvertieren, dass er einer exponierten Methode zugeordnet werden kann. Bei einer begrenzten Anzahl an zur Verfügung gestellten Methoden wird das üblicherweise mit einer Select Case-Anweisung gelöst, was hier wegen dem Anspruch an Allgemeingültigkeit der RS.ASP nicht möglich ist. JScript stellt hier die Funktion eval() zur Verfügung, die die beschriebene Konvertierung vornimmt. Sie erzeugt einen Verweis zu der durch den String dargestellten Funktion. Die eval()-Funktion in VBScript wertet hingegen nur mathematische Ausdrücke aus.

Einer der Hauptgründe ist aber sicherlich, daß zum Zeitpunkt des Erscheinens von Remote Scripting in VBScript noch keine Erstellung von Klassen möglich war, was mittlerweile aber behoben ist.

Mit der obigen ASP Seite haben wir den Server vorbereitet, Remote Scripting-Aufrufe zu empfangen. Wir wollen die Server-Funktionen allerdings clientseitig per JavaScript aufrufen - es ist also noch etwas Arbeit am Client erforderlich.

Die folgende HTML-Datei skizziert den Aufbau eines beispielhaften Remote Scripting-Callers (3.HTM).

<html>
   <head>
        <script
               language=JavaScript
               src=_ScriptLibrary/RS.HTM>
        </script>
        <script
             language=JavaScript>
             RSEnableRemoteScripting("_ScriptLibrary");
        </script>
   </head>

    <body>
        <p>Das hier kam vom Server:</p>
        <script
            language=JavaScript>
            document.open();
            var RSObject =
                RSExecute('4.ASP','MeineFunktion');
            document.write(RSObject.return_value);
            document.close();
        </script>
	
    </body>
</html>

Wie hieraus ersichtlich wird, ist es mit diesem Konstrukt schon möglich, Werte auf dem Server zu erzeugen und ohne erneutes Laden der Seite im Browser darzustellen. Ohne weitere Schwierigkeiten kann jetzt ein Pseudo-State eingeführt werden.

Als Beispiel wollen wir die Verweildauer eines Benutzers auf einer Seite in das Session-Objekt schreiben. Auf dem Server ist das relativ unspektakulär (4.ASP):

<%@ LANGUAGE=VBScript %>
<!--#INCLUDE FILE=_ScriptLibrary/RS.ASP--
<SCRIPT LANGUAGE=Jscript RUNAT=SERVER>
RSDispatch();
function MyServerMethods() 
{
    this.setUserOnTime =
       Function(
       "return SetUserOnTime();");
}
var public_description = new MyServerMethods();
</SCRIPT>
<%
    Function SetUserOnTime()
    Session("UserOnTime") = Session("UserOnTime") + 1
    End Function
%>

Hier wird die VBScript-Funktion SetUserOnTime exponiert. Der eigentliche Vorgang des Aktualisierens der Verweildauer geschieht im VBScript-Bereich.

Beim Client ist ein kleiner Kniff notwendig, um den User nicht mit Wartezeiten zu belästigen (5.HTM).

<html>
    <head>
        <script
            language=JavaScript
            src=_ScriptLibrary/RS.HTM>
        </script>
        <script language=JavaScript>
            RSEnableRemoteScripting();

            window.setTimeout(1000,"SetUserOnTime();");

            function SetUserOnTime()
            {
                RSExecute(
                    "OnTime.ASP",
                    "SetUserOnTime",
                    SetUserOnTimeCallBack();
                );
            }
            function SetUserOnTimeCallBack() 
            {
              // nichts tun..
            }
        </script>
    </head>
    <body>
        <p>Bitte warten Sie hier ein bißchen...</p>
    </body>
</html>

Wir rufen hier mit Hilfe eines JavaScript-Intervalls die Funktion SetUserOnTime() (dieses Mal clientseitig) einmal pro Sekunde auf. Dabei fragen wir jetzt allerdings keine Rückgabewerte ab - nicht nur deswegen, weil unsere serverseitige Methode keine Rückgabewerte hat, sondern vor allem deswegen, weil wir mit der Funktion SetUserOnTimeCallBack() eine sogenannte CallBack-Funktion definiert haben.

Das Processing beim Client wartet also nicht, bis unsere Server-Methode ausgeführt wurde, sondern schickt den Request zum Server und ruft erst nach Vervollständigung des Prozesses eine andere Client-Funktion auf. Das ist in diesem Falle ein Workaround - Remote Scripting erkennt einen Aufruf, bei dem eine CallBack-Funktion definiert wurde, als asynchronen Remote Scripting-Call an und lässt damit den Client während der Ausführung andere Dinge tun.

Beim User sieht das Ganze nach einer recht statischen Seite aus - vor allem weil es hier möglich ist, Standard-HTML-Format zu verwenden. Man braucht durch die simplen JavaScript-Calls keinerlei serverseitige Technologie (außer eben die ASP, in der die Server-Methoden exponiert sind).

Wir rufen hier mit Hilfe eines JavaScript-Intervalls die Funktion SetUserOnTime() (dieses Mal clientseitig) einmal pro Sekunde auf. Dabei fragen wir jetzt allerdings keine Rückgabewerte ab - nicht nur deswegen, weil unsere serverseitige Methode keine Rückgabewerte hat, sondern vor allem deswegen, weil wir mit der Funktion SetUserOnTimeCallBack() eine sogenannte CallBack-Funktion definiert haben.

Das Processing beim Client wartet also nicht, bis unsere Server-Methode ausgeführt wurde, sondern schickt den Request zum Server und ruft erst nach Vervollständigung des Prozesses eine andere Client-Funktion auf. Das ist in diesem Falle ein Workaround - Remote Scripting erkennt einen Aufruf, bei dem eine CallBack-Funktion definiert wurde, als asynchronen Remote Scripting-Call an und lässt damit den Client während der Ausführung andere Dinge tun.

Beim User sieht das Ganze nach einer recht statischen Seite aus - vor allem weil es hier möglich ist, Standard-HTML-Format zu verwenden. Man braucht durch die simplen JavaScript-Calls keinerlei serverseitige Technologie (außer eben die ASP, in der die Server-Methoden exponiert sind).

Schlußbemerkung

Durch die Einführung von States in Webanwendungen, die eigentlich per Definitionem stateless sind, ist es nun möglich, typische Web-Problematiken, die in GUI-Anwendungen ohne weiteres lösbar sind, auf elegante Art und Weise zu umgehen.

Lernen Sie in nachfolgenden Artikeln zu diesem Thema, wie Sie eine VB-Applikation mit Formularen und Steuerelementen via Remote Scripting ins Web portieren. Lernen Sie die Grenzen und Probleme der Remote Scripting-Technologie kennen und schaffen Sie durch das so erlernte Wissen Workarounds zu diesem Thema.

This printed page brought to you by AlphaSierraPapa

Download des Codes

Klicken Sie hier, um den Download zu starten.
http://www.aspheute.com/code/20010125.zip

Verwandte Artikel

Onlinestatus des Users über RemoteScripting ermitteln
http:/www.aspheute.com/artikel/20010628.htm
RemoteScripting - Einführung, Tips und Tricks
http:/www.aspheute.com/artikel/20010606.htm

Links zu anderen Sites

MSDN - Remote Scripting
http://msdn.microsoft.com/scripting/remotescripting/default.htm

 

©2000-2006 AspHeute.com
Alle Rechte vorbehalten. Der Inhalt dieser Seiten ist urheberrechtlich geschützt.
Eine Übernahme von Texten (auch nur auszugsweise) oder Graphiken bedarf unserer schriftlichen Zustimmung.