Re: COM+ Hölle
- From: "Schmidt" <sss@xxxxxxxxx>
- Date: Sat, 14 Jan 2006 17:22:53 +0100
"Peter" <Peter@xxxxxxxxxxxxxxxxxxxxxxxxx> schrieb im Newsbeitrag
news:0BEB928D-872A-4D64-9B4B-327E885A18D0@xxxxxxxxxxxxxxxx
> Unser AX-Exe kümmert sich im Wesentlichen nur noch um
> die Kommunikation zwischen Server und den Clients.
> Diese lassen wir bewußt synchron ablaufen, denn so können
> wir den Synchronisationsmechanismus der DLL auch für unsere
> Clients nutzen (anfangs dachten wir noch an eine simple TCP/IP
> Kommunikation via Winsock, aber ganau dann hätten wir den
> Server selbst synchronisieren müssen).
Ich fragte diesbezüglich deshalb nach den Details, weil unser Server auf
Basis einer definierbaren Anzahl von Worker-Threads arbeitet, so dass
die von mehreren Clients kommenden RPCs parallel ausgeführt werden
können. Innerhalb eines Clients erfolgt der RPC aber synchron (es wird
also auf die Response (bis zum Erreichen des TimeOuts) gewartet, bevor
mit der Programmausführung fortgefahren wird.
Eure Steuerungs-Dll müsste also im Kontext unseres Serverprozesses
"threadsafe" mit parallelen Requests umgehen können - alternativ wäre
sonst ein separater COM-Singleton zwischenzuschalten, um eventuell
parallel einlaufende Calls unterschiedlicher Clients vor dem Ansprechen
eurer Steuerungs-Dll zu serialisieren (was aber kein großes Problem wäre).
Aber wenn ich Dich richtig verstanden habe, kann eure Dll das schon
"von Haus aus".
> Was habt ihr euch denn gestrickt?
Einen eigenen socketbasierten "(D)COM(+)-Ersatz" (Ok, COM+ ist als
Transaktionsmonitor schon noch etwas mehr, unser Ansatz ist vielleicht
eher vergleichbar mit binärem .NET-Remoting), bestehend aus einer
Serveranwendung und einer zugehörigen Client-Dll. Das Tool ist einfach
in der Lage, COM-RPCs über TCP/IP abzuwickeln und das im
Vergleich zu DCOM (welches einen ganzen Port-Range benötigt) über
nur einen Port (also "Firewall-Config-freundlich").
Ein automatisches Marshaling (Proxy/Stub-Pairs) von COM+
(bzw. DCOM), welches eine registrierte und zueinander passende
Schnittstelle sowohl auf Server - als auch auf Clientseite voraussetzt,
haben wir nicht nachgebildet.
Auf dem Client wird einfach vorausgesetzt, dass der Programmierer die
Signatur (stimmige Parameter usw.) einer serverseitig auszuführenden
Funktion korrekt bedient. Er muss sich seinen Wrapper (seine Proxy-
Klasse) für die serverseitig anzusprechende COM-Schnittstelle also
selbst schreiben.
Das hat - abgesehen vom (nicht gar so schlimmen) Kodieraufwand für
die Wrapperklasse - verschiedene Vorteile:
Zunächst mal kann der Server die in seinen Dll-Verzeichnissen liegenden
COM-Binaries ausführen, ohne die Registry zu bemühen. Er interessiert
sich also überhaupt nicht für die Interface-IDs oder irgendwelche
speziellen COM+-Benutzerrechte.
Clientseitig muss weder die InterfaceID der Serverklasse, noch die der
Wrapperklasse bekannt oder registriert sein (Wrapperklassen können
auch 'Private' innerhalb einer Standard-Exe sitzen).
Man muss, um einen RPC auszuführen, nicht mal eine Wrapperklasse
schreiben, wenn man nicht möchte.
Das alles hat den Vorteil, dass Registry- bzw. Dll-Hell komplett
vermeidbar sind und Updates der serverseitigen COM-Binaries auch
im laufenden (Server-)Betrieb erfolgen können.
Da der Server sich nicht für die InterfaceIDs in der Registry interessiert,
sondern direkt aus dem Filesystem heraus instanziiert, muss beim
Hochladen neuer Server-Dlls nicht auf Einhaltung der Binärkompatibilität
geachtet werden, sondern nur darauf, dass innerhalb der Wrapperklassen
die eventuell veränderten (bzw. zumeist nur die hinzugekommenen)
Methodensignaturen korrekt bedient werden.
Wenn eine Methode (in einer serverseitigen COM-Dll) z.B. so aussieht:
(serverseitige ByRef-Parameter müssen immer Variants sein -
für Byval-Params ist alles erlaubt ausser Objekten und Types)
Public Function DoIt(P1, Byval P2 as Long) as String
'...
End Function
Dann wäre in der Proxy-Klasse, die das Interface der Server-Dll
nachbildet, folgendes zu schreiben:
(für eine große Anzahl an Wrapper-Klassen sollte Cnn "ausserhalb",
also "Prozess-Global" instanziiert und dann in die Wrapperklasse
hineingegeben werden)
Private Const DllFileName$ = "AServer-COM.Dll"
Private Const ClassName$ = "AClassName" 'public inside the Dll
Private Cnn As cRPCHelper
Private Sub Class_Initialize()
Set Cnn = New cRPCHelper
Cnn.IP = ServerIP
Cnn.Port = ServerPort
Cnn.Compression = False 'use True for large serialized responses
Cnn.DefaultTimeOut = 10 'seconds
Cnn.KeepAlive = True 'don't reconnect for each RPC
Cnn.Connect
End Sub
'********Begin Method-Wrapping*********
'PSpecial is used, to overrwrite the DefaultTimeOut with
'Method-specific Timeout-Values - if RPC returns, PSpecial
'contains the Error-Descriptions (TimeOut-Errors, CallErrors, etc.)
Public Function DoIt(P1, Byval P2 as Long) as String
Dim PSpecial
PSpecial = 5 'synchronized Call, so specify a Timeout-Value (in seconds)
DoIt = Cnn.RPC(PSpecial, DllFileName, ClassName, "DoIt", P1, P2)
If Len(PSpecial) Then Err.Raise ErrNrOffs + 1, , PSpecial
End Function
> Zwischen 5 und max. 15 Clients.
Ok, dann reicht die einfachere Variante unseres Servers
(max. 64 gleichzeitige Connects).
> Noch eine Frage:
> Habt ihr evt. schon Erfahrungen mit .NET bezüglich dieses
> Remotings gemacht.
Ja, in der Anfangsphase von .NET war Remoting noch langsamer
als unsere RPC-Implementierung - inzwischen hat MS nachgebessert
und (binäres) .NET-Remoting ist jetzt etwa gleich schnell.
Schaltet man bei uns dann noch Kompression und Verschlüsselung ein,
so fällt .NET-Remoting (bei vergleichbarer Konfiguration) wieder ab.
Remoting innerhalb des .NET-Frameworks ist aber inzwischen schon
wieder "deprecated" und der Einsatz von WSE (Web Service
Enhancements) wird empfohlen. Mit WSE (bzw. dessen Performance)
haben wir uns aber noch nicht beschäftigt.
> Wir würden das Ganze mittelfristig gerne auf VB.NET oder C#
> umschreiben; auch könnten wir den Server dann sehr einfach als
> Dienst laufen lassen (die ständig laufende Sitzung ist nicht
> sonderlich profesionell ;-)
Unser kleiner RPC-Server kann (noch) nicht als Dienst laufen - aber ich
schau mal, ob ich das noch integriere.
> Das macht aber natürlich nur Sinn, wenn genau diese Probleme
> dort besser zu handeln sind. Oder müssen die .NET Assemblies
> als COM Klassen registriert werden, die dann wieder unter COM+
> laufen müssen (mit den selben Problemen).
Das mussten (in der "Prä-WSE-Ära") .NET-Klassen nur, wenn die
Transaktions-Mechanismen von COM+ Anwendung finden sollten
("normale" RPCs via IIS-Webservices oder Remoting funktionierten
immer schon auch ohne COM+ und den entspr. COM-Wrappern).
Inzwischen lässt sich WSE wohl (bin kein WSE-Experte) sowohl in
COM+, im IIS, als auch in der eigenen Anwendung hosten.
Olaf
.
- References:
- Re: COM+ Hölle
- From: Schmidt
- Re: COM+ Hölle
- Prev by Date: Re: Windows-Ereignis für Dateizugriff, Öffnen, Speichern Schließen
- Next by Date: Re: Active-X Problem
- Previous by thread: Re: COM+ Hölle
- Next by thread: Re: Windows-Ereignis für Dateizugriff, Öffnen, Speichern Schließen
- Index(es):
Relevant Pages
|