Ludger: "Komponenten"

Hi,

ich moechte gerne unserer Client Server Architektur ein neues Element beifuegen, dem ich den Arbeitstitel
 Komponente
gegeben haben.

An Hand eines einfachen Beispiels erlaeutere ich:
Wir holen Auskuenfte verscheidener Auskunfteien. Diese sollen von der Komponente abgeholt und dann an den Client geliefert werden. Die Kommunikation zwischen der Komponente und den Auskunfteien erfolgt per beliebiger Schnittstelle und Protokoll, interessiert also hier nicht. Die Kommunikation zwischen Abnehmer (interne Clientanwendung oder eine unserer Serveranwendungen) und Komponente erfolgt HTTP(S) XML-basiert. Nun gibt es die asynchron auszufuehrenden Anfragen des Abnehmers und die synchron auszufeuhrenden. Erstere sind kein Problem, zweite sind erforderlich wegen der teilweise langen Reaktionszeiten der Systeme der Auskunfteien. Die Komponente muesste also dem Abnehmer (muss kein Webserver sein) den Erhalt der Auskunft melden. Dafuer haben wir was auf TCP/IP-Ebene gebastelt. Allerdings muesste dann eine zweite Komponente (ich nenne die mal Meldekomponente) den Client pollen.

Frage: Was haltet Ihr vom oben beschriebenen Konzept? Ist das OK? Verbesserungsvorschlaege und Kritk sehr willkommen. Gibts eine Moeglichkeit den TCP/IP-Teil rauszunehmen?

Gruss,
Ludger

  1. Hi,

    Frage: Was haltet Ihr vom oben beschriebenen Konzept? Ist das OK?

    Du müsstest es sehr viel detaillierter beschreiben (am besten auch mit graphischer Unterstützung), bis ich eine Beurteilung wagen würde. Auf den ersten Blick springen mir allerdings einige Begriffe entgegen, die Du nicht erwähnst und von denen ich daher annehme, dass sie Dir helfen könnten, nämlich vor allem Web Services (Stichwort z.B. WSDL) und Long bzw. Unknown Duration Transactions.

    Cheatah

    --
    X-Self-Code: sh:( fo:} ch:~ rl:° br:> n4:& ie:% mo:) va:) de:] zu:) fl:{ ss:) ls:~ js:|
    X-Self-Code-Url: http://emmanuel.dammerer.at/selfcode.html
    X-Will-Answer-Email: No
    X-Please-Search-Archive-First: Absolutely Yes
    1. Hi,

      Du müsstest es sehr viel detaillierter beschreiben (am besten auch mit graphischer Unterstützung), bis ich eine Beurteilung wagen würde.

      nun, ich bin noch in der Pre-Planungsphase.   ;-)

      Also, diese Auskunftskomponente, die hat Webanwendungen und rich clients als Abnehmer. Und die liefert ihre Leistung entweder sofort oder spaeter. Das mit dem sofort ist kein Problem, da kaeme dann ein wie auch immer gearteter Webservice ("low level" oder SOAP) in Frage.

      Die besondere Herausforderung besteht m.E. in den asynchron zu bearbeitenden Requests der Webanwendung oder des rich clients. Bei genauerer Uberlegung geht es um die rich clients, VB6 Prograemmchen zum Beispiel. Diese koennten  von einer zweiten Komponente ueber den Eingang einer Auskunft benachrichtigt werden (mittels einer TCP/IP-irgendwas Loesung, auch auf dem Austausch von XML-Dokumenten basierend). Alternativ koennte man fordern, dass die rich clients halt immer wieder mal anfragen muessen, ob was gekommen ist.

      Und da weiss ich nicht so recht, was ich machen soll. Die TCP/IP Komponente will ich zum Beispiel nicht, das Pullen der rich clients macht mich nicht ganz happy und ein server push auf HTTP(S)-Ebene geht nicht.

      Auf den ersten Blick springen mir allerdings einige Begriffe entgegen, die Du nicht erwähnst und von denen ich daher annehme, dass sie Dir helfen könnten, nämlich vor allem Web Services (Stichwort z.B. WSDL) und Long bzw. Unknown Duration Transactions.

      Ja, das mit den transactions hoert sich ganz gut an. Wie bearbeitet man also "profikorrekt" solche Anforderungslagen. Kommt man da mit Warteschlangen oder sowas? MSMQ faellt mir da so ein, will ich aber nicht. WSDL ist doch die Sprache mit denen diese XML-Proxies generiert werden koennen, oder?

      Gruss,
      Ludger

      1. Hi,

        Die besondere Herausforderung besteht m.E. in den asynchron zu bearbeitenden Requests der Webanwendung oder des rich clients.

        ja. Das betrifft das Thema Unknown Duration Transactions, welches eben diese Asynchronität abbildet.

        Bei genauerer Uberlegung geht es um die rich clients, VB6 Prograemmchen zum Beispiel. Diese koennten  von einer zweiten Komponente ueber den Eingang einer Auskunft benachrichtigt werden

        In einer "echten Client-Server-Welt" (was immer das sein mag ;-) würde dann aus dem Client ein Server werden. Der vorherige Request ist abgeschlossen, der Response gesendet; nun muss von der Komponente ein neuer Response aus abgefeuert werden, was nicht geht - es ist ein Request in umgekehrter Richtung. Natürlich kannst Du die Verbindung nach dem Schnell-Response ("Nachricht erhalten, wird bearbeitet") offen halten und den Client auf weitere Ergebnisse warten lassen, was aber je nach Transaktionsdauer durchaus auch riskant sein kann. Es schränkt Dich zudem in der Wahl der Protokolle ein.

        (mittels einer TCP/IP-irgendwas Loesung,

        Wenn möglich, würde ich ein etabliertes Protokoll wählen, anstatt selbst eines zu erfinden.

        Alternativ koennte man fordern, dass die rich clients halt immer wieder mal anfragen muessen, ob was gekommen ist.

        Das geht natürlich auch, es erinnert an einen Mailclient. Dadurch gibt es gewisse Sicherheiten, z.B. werden die Nachrichten auch bei einem Ausfall des Servers "irgendwann" ankommen; aber natürlich leidet die Geschwindigkeit darunter. Zudem werden sich beide Seiten gewisse Dinge merken müssen (und sei es nur ein Identifier), was bei anderen Lösungen nicht bzw. nicht so stark gegeben ist.

        Und da weiss ich nicht so recht, was ich machen soll.

        Tipp: Eine Zeichnung. Auf Papier. Mal Dir auf, was für "Dinge" Du hast, wie die Kommunikation verläuft und was wo und wann Probleme ergeben kann. Nach meiner Erfahrung wird einem so oft genug plötzlich klar, in welche Richtung die Lösung gehen muss.

        Ja, das mit den transactions hoert sich ganz gut an. Wie bearbeitet man also "profikorrekt" solche Anforderungslagen. Kommt man da mit Warteschlangen oder sowas?

        Queuing ist dabei ein sehr wichtiges Thema, welches IMHO auf jeden Fall einbezogen werden sollte - und sei es nur als Fallback, wenn eine der Komponenten ausfällt.

        MSMQ faellt mir da so ein, will ich aber nicht.

        Kann ich nichts zu sagen.

        WSDL ist doch die Sprache mit denen diese XML-Proxies generiert werden koennen, oder?

        Es ist die Sprache, in der Web Services beschrieben werden (Web Service Description Language :-), also mit der gesagt wird, was ein spezieller Web Service "tut". Auch ein Proxy kann ein solcher sein. Wenn man sich intensiv damit beschäftigt, kommt man zwangsläufig zum Semantic Web und Ontologien, aber das führt bei Dir vermutlich deutlich zu weit. Für Dich ist vor allem wichtig, dass Deine Komponenten Web Services _sind_, und dass Du entsprechende (vorhandene) Techniken damit verbinden kannst.

        Cheatah

        --
        X-Self-Code: sh:( fo:} ch:~ rl:° br:> n4:& ie:% mo:) va:) de:] zu:) fl:{ ss:) ls:~ js:|
        X-Self-Code-Url: http://emmanuel.dammerer.at/selfcode.html
        X-Will-Answer-Email: No
        X-Please-Search-Archive-First: Absolutely Yes
  2. Hallo,

    also ich habe was Ähnliches Client-Server-mäßiges (wenn ich dich richtig verstanden habe) gebastelt. Vielleicht hilft es Dir ja.

    -->Zuerst habe ich eine Webapplikation auf ASP-Basis. Da steht im Code sowas:

    <%
    Response.ContentType = "Application/VbIeClient"
    %>
    <report Projekt="<%=Request.querystring("Projekt")%>" Report="<%=Request.querystring("Report")%>" DokNr="<%=Request.querystring("DokNr")%>" DokDatum="<%=Request.querystring("DokDatum")%>" ip="<%=Request.ServerVariables("LOCAL_ADDR")%>" secure="n"/>
    <%
    response.end
    %>

    -->Das wird über den Browser aufgerufen. Auf den Rechnern mit dem Client ist ein Dateityp/Anwendung für die Application registriert.

    -->Der Client (VB6, da unter Win98 laufen soll) öffnet sich.

    --> Im Client arbeite ich die das XML-Kommando ab. (xmlDoc.Load(Command$))

    --> Wenn der Client noch was vom Server braucht, nutze ich folgende Funktionen:

    Public Function getFileFromServer(serverpath As String, FileName As String, savepath As String) As Boolean
        Dim xmlHttpReq As MSXML2.XMLHTTP30
        Dim fi As Long
        getFileFromServer = False
        On Error GoTo SendFileError
        Set xmlHttpReq = New MSXML2.XMLHTTP30
        xmlHttpReq.open "get", serverpath & FileName, False
        xmlHttpReq.send
        If xmlHttpReq.Status <> 200 Then
            ErrorMessage = "Die Verbindung zum Server ist fehlgeschlagen! (Http Request POST " & xmlHttpReq.Status & ")"
            Set xmlHttpReq = Nothing
            Exit Function
        End If
        fi = FreeFile
        Open savepath & "" & FileName For Output As #fi
        Print #fi, xmlHttpReq.responseText
        Close #fi
        getFileFromServer = True
        Set xmlHttpReq = Nothing
        Exit Function
    SendFileError:
        ErrorMessage = "Die Datei konnte nicht auf dem Server gefunden werden!"
        Set xmlHttpReq = Nothing
    End Function

    -->bzw. wenn er was an den Server senden soll:

    Public Function sendXMLToServer(xmlDoc As DOMDocument30, DataxmlDoc As MSXML2.DOMDocument30) As Boolean
        Dim xmlHttpReq As MSXML2.XMLHTTP30
        sendXMLToServer = False
        On Error GoTo SendXMLError
        Set xmlHttpReq = New MSXML2.XMLHTTP30
        xmlHttpReq.open "post", serverpath & "/RecieveXML.aspx", False
        xmlHttpReq.setRequestHeader "Content-type", "text/xml"
        xmlHttpReq.send xmlDoc.xml 'string/array to send
        If xmlHttpReq.Status <> 200 Then
            ErrorMessage = "Die Verbindung zum Server ist fehlgeschlagen! (Http Request POST " & xmlHttpReq.Status & ")"
            Set xmlHttpReq = Nothing
            Exit Function
        End If
        Set DataxmlDoc = New MSXML2.DOMDocument30
        DataxmlDoc.async = False
        'MsgBox xmlHttpReq.responseText
        If DataxmlDoc.loadXML(xmlHttpReq.responseText) = False Then
            ErrorMessage = "Es ist ein Fehler beim Laden der Daten aufgetreten!"
            Set xmlHttpReq = Nothing
            Exit Function
        End If
        If DataxmlDoc.documentElement.baseName = "error" Then
            ErrorMessage = DataxmlDoc.documentElement.firstChild.Text
            Set xmlHttpReq = Nothing
            Exit Function
        End If
        sendXMLToServer = True
        Set xmlHttpReq = Nothing
        Exit Function
    SendXMLError:
        ErrorMessage = "Die Datei konnte nan den Server gesendet werden!"
        Set xmlHttpReq = Nothing
    End Function

    -->Die Datei RecieveXML.aspx nimmt auf Serverseite wieder XML entgegen:

    Dim commandXMLDoc As New Xml.XmlDocument

    Private Sub writeError(ByVal txt As String)
            Response.Write("<error><!-- " & txt & " --></error>")
        End Sub
        Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            ' Hier Benutzercode zur Seiteninitialisierung einfügen
            commandXMLDoc.LoadXml(httpInputToString(Request))
            Try
                getResponse()
            Catch ex As Exception
                writeError(ex.Message)
            End Try
        End Sub

    Vielleicht nicht so ganz was Du machen willst, aber vielleciht hilfts ja weiter....
    -LeKuchen