Lotus.NET

    • Beta

    Es gibt 13 Antworten in diesem Thema. Der letzte Beitrag () ist von BeefyX.

      Name der Bibliothek:
      Lotus.NET

      Beschreibung:
      Mit Lotus.NET lassen sich sehr einfach verteilte Anwendungen erstellen, bei denen Methoden nativ auf dem Server ausführbar sind, als wären sie im Client selbst. Um das ganze besser verständlich zu machen, habe ich mir mal die Zeit genommen, ein kleines Beispiel vorzubereiten.

      Beispiel:
      Spoiler anzeigen
      Zuerst muss für einen Netzwerkservice ein gemeinsames Interface definiert werden, dass Client und Server kennen.

      VB.NET-Quellcode

      1. 'Funktionen, die der Service bereitstellt
      2. Public Interface IService
      3. Function SayHello(ByVal a As String) As String
      4. End Interface


      Dabei werden im Interface alle Methoden definiert, die gemeinsam genutzt werden. Anschließend implementieren wir die Methode in den Server:

      VB.NET-Quellcode

      1. Imports Lotus
      2. Public Class ServiceHost : Inherits HostBase(Of IService) : Implements IService
      3. 'SayHello-Methode auf Serverseite. Durch das NetworkMethod Attribut
      4. 'weiß Lotus, dass diese Methode als Netzwerkmethode gekennzeichnet ist.
      5. <NetworkMethod()> _
      6. Public Function SayHello(a As String) As String Implements IService.SayHello
      7. Return "Hello " & a
      8. End Function
      9. 'Host initialisieren und auf Port 8000 starten
      10. Public Sub New()
      11. MyBase.Initialize(Me)
      12. MyBase.Host.Start(8000)
      13. End Sub
      14. End Class


      Soweit so gut, um die Methode im Client nutzen zu können, ist das ganze etwas komplizierter.

      VB.NET-Quellcode

      1. Imports Lotus
      2. Public Class ServiceClient : Inherits ClientBase(Of IService) : Implements IService
      3. 'SayHello Methode auf Client-Seite
      4. Public Function SayHello(ByVal a As String) As String Implements IService.SayHello
      5. '
      6. ' Die Methode "SayHello" mit den Argumenten "a" und
      7. ' dem Rückgabewert vom Typ String auf dem Server ausführen.
      8. '
      9. ' Alle Konfigurationsmöglichkeiten im Überblick:
      10. '
      11. ' .Method: Methodenname der auszuführenden Methode
      12. ' .WithArguments: Argumente, die der Methode übergeben wurden
      13. ' .WithGeneric: Falls generische Parameter mit angegeben werden, diese übergeben
      14. ' .Return(Of T): Methode ausführen und Rückgabewert vom Typ T zurückgeben
      15. ' .Execute: Methode ausführen, kein Rückgabewert
      16. '
      17. Return MyBase _
      18. .Method("SayHello") _
      19. .WithArguments(a) _
      20. .Return(Of String)()
      21. End Function
      22. 'Client initialisieren und auf 127.0.0.1:8000 verbinden
      23. Public Sub New()
      24. MyBase.Initialize(Me)
      25. MyBase.Client.Connect("127.0.0.1", 8000)
      26. End Sub
      27. End Class


      Das ist im Prinzip auch schon alles, um einen gemeinsamen Service zu erstellen. Der Client kann jetzt auf den Server connecten und anschließend die Methoden in der Client-Klasse aufrufen, die dann auf dem Server ausgeführt werden.
      Dazu ein Beispielmodul:

      VB.NET-Quellcode

      1. Imports Lotus
      2. Imports Lotus.Authentification
      3. Module LotusTest
      4. Sub Main()
      5. 'Unsere Servicekomponenten initialisieren
      6. Dim serviceHost As New ServiceHost
      7. Dim serviceClient As New ServiceClient
      8. 'Protokoll und Transfermodus auf Standardwerte setzen
      9. Network.Protocol = Protocol.TCP
      10. Network.TransferMode = TransferMode.Default
      11. 'Wichtig, um das Authentifizierungssystem zu deaktivieren,
      12. 'das für unsere Zwecke nicht nötig ist.
      13. serviceHost.Host.SecurityManager.SecurityMode = SecurityMode.None
      14. 'Die Methode "SayHello" wird im Server ausgeführt und der Rückgabewert
      15. 'an den Client zurückgesendet
      16. Dim helloWorld As String = serviceClient.SayHello("World")
      17. 'Ergebnis ausgeben
      18. Console.WriteLine(helloWorld)
      19. Console.ReadLine()
      20. End Sub
      21. End Module


      Eine vollständige Dokumentation wird die Tage folgen, inklusive einem Tutorial, mit dem man Shared Properties erstellen kann, die dann im Client nativ genutzt werden können.

      Beispielprojekt herunterladen (120KB)

      Verwendete Programmiersprache:
      Visual Basic .NET (IDE: Visual Studio 2010 Professional)

      Systemanforderungen:
      .NET Framework 4.0

      Download:
      Download Lotus.NET (17 KB)

      Lizenz/Weitergabe:
      Closed Source, Mergen ist nicht erlaubt, nur für nicht-kommerzielle Projekte.

      Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „Krissel095“ ()

      Sieht wirklich nett aus. Hätte ich letztens gebraucht - wenn ich das richtig verstanden habe, ist das soetwas ähnliches wie ein WCF-Dienst, oder?
      Von meinem iPhone gesendet

      Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „nikeee13“ ()

      Danke :)
      Bzw. ist das nicht wirklich nen Webverweis, wenn man (jetzt mal aus dem Beispiel) die Methode SayHello aufruft:

      VB.NET-Quellcode

      1. Dim helloWorld As String = serviceClient.SayHello("World")


      Dann wird diese auf dem Server ausgeführt. Ist vllt. in dem Beispiel nicht ganz so deutlich sichtbar, weil ja Server und Client im selben Programm laufen, aber letztendlich kann man Methoden, die sich auf dem Server befinden, auf dem Client ausführen, als wäre man im Serverprogramm. D.H. anstatt umständlich irgendwelche Pakete über TCP zu senden und auf eine Response zu warten, lässt sich das über Methoden, die Rückgabewerte besitzen regeln.

      Was im Beispiel nicht gezeigt wurde: Das Sytem hat außerdem ein umfangreiches Security-System, sodass bestimmte Methoden nur mit bestimmten Berechtigungen auf dem Server ausgeführt werden können und man somit einige Methoden (z.B. zum Bannen von Usern im Fallbeispiel eines Chats) nur für authentifizierte Admins verfügbar machen kann.



      Hoffe es ist jetzt etwas klarer, was Lotus genau ist ;)

      MfG
      Theoretisch ja, solange man pro zu verwendenen Serverthread einen Client instanziert. Jeder Client wird auf dem Server in einem eigenen Thread ausgeführt, d.H. dass bei mehreren Clients auch mehrere Threads auf dem Server verfügbar sind. Praktisch getestet habe ich das bisher allerdings noch nicht, ich denke aber, das sollte kein Problem sein ;)

      MfG
      Nein, das meinte ich nicht. Ich meinte folgendes: Man deklariert einen Client;und einen Server; im Client Programm greifen mehrere Threads async. auf das Client-Controll zu, und senden die Daten an den Server. Geht dies, oder können dort Fehler auftreten?
      Danke für den Hinweis, daran habe ich bisher noch nicht gedacht. Ich hab eben mal Multithreading Support sowohl auf Client-, als auch auf Serverseite für dein Fallbeispiel eingebaut. Da asynchrones lesen bzw. schreiben innerhalb eines Netzwerkstreams sehr unschön ist, arbeitet die Version mit einem simplen Lock. Bis auf die Sende- und Empfangsvorgänge sollte aber alles andere asynchron möglich sein.

      Download Lotus.NET: Download (Stable Release, 17KB)

      MfG
      Letztendlich könnte man die Performance nochmal ein wenig verbessern, wenn man mithilfe eines Hashmappings nicht den gesamten Methodennamen serialisiert, sondern einfach ein 4-Byte Hash an den Server sendet, der dann das selbe Hashmapping verwendet wie der Client.

      Btw., die Attribute werden einfach über Reflection ausgelesen, damit Lotus weiß, welche Methoden der Client ausführen darf und welche nicht. Letztendlich werden die Methoden intern in ein Dictionary gemappt und bei Anfragen des Clients ausgeführt. Mehr als ein Serialisierungs- und Reflectionsystem steckt da nicht hinter ;)

      Edit: Es ist übrigens, falls noch Interesse besteht, eine neue Version geplant. Die neue Version funktioniert dann aber sehr wahrscheinlich wie das Channel-System von WCF, also ohne explizite Angabe der Methodenstruktur im Client. Außerdem werde ich versuchen ein paar Performance Improvements zu implementieren, wie eben schon angesprochen ;D

      MfG
      Wie stellst du dir asynchrone Lese- und Schreibvorgänge in einem TCP Stream vor? ;) Die Threads in Client und Server laufen ja nicht genau gleich, d.H. die Daten könnten dann bei asynchronen Lese- und Schreibvorgängen auch in die falschen Threads gelangen.

      Die Implementierung über Locking dürfte das Problem aber lösen, einen merkbaren Nutzungsunterschied macht es nicht.

      MfG
      Seit ich weiss wie man asynchrone Vorgänge beginnt, verwende ich keine Threads mehr im Tcp Server. Nichtmal für Clients. Alles in einem Thread.
      Das erscheint für mich auch sehr Logisch, da in einem Thread doch alles nacheinander abgearbeitet wird, und in 2 Threads wird halt alles recht gleichzeitig geschehen.