Wenn dein Problem oder deine Frage geklärt worden ist, markiere den Beitrag als "Lösung",
indem du auf den "Lösung" Button rechts unter dem entsprechenden Beitrag klickst. Vielen Dank!
' schrieb:damit ich dir die VIs zeigen kann müsste ich die aus den Projekten rausziehen, aber da ist eine NDA drauf => keine gute Idee und "veröffentlichbar" nachprogrammieren .... hmmm ... keeene zeit, keene lust
aber ich versuchs mal zu erklären:
in meinem Server VI gibts mehr oder weniger 2 parallele Schleifen.
Die eine wartet ständig auf eine eingehende Verbindung, nimmt diese an und startet dynamisch - wenn was reingekommen ist - ein reentrantes VI, das nenn ich mal "Client VI". Die zweite Schleife im Server ist eine queued state machine, die quasi "die Arbeit verrichtet".
Jedes Client VI erzeugt bei seinem Start eine eigene Queue und hat eine "mini Statemachine". Damit das Client VI möglichst klein ist und wenig Ressourcen benötigt, besteht das VI mehr oder weniger nur aus ein paar Queue und TCP funktionen.
Der "Trick" dabei ist, die "Arbeit" vom Server verrichten zu lassen, und das Senden und Empfangen über TCP durch die "Client VIs". Das ist wichtig, damit sich verschiedene Clients nicht gegenseitig blocken können, z.B. wenn der Versand von Daten bei einer Anfrage an den Server mal was länger dauert oder so.
Wenn das Client VI eine Anfrage vom Client empfängt, dann wird diese geparst und in die Queue der StateMachine des MainVIs geschoben. Neben dem Befehl und den Daten bekommt das MainVI noch die Queue Referenz von der Q des jeweiligen Client VIs, wo nach dem Abarbeiten die "Antwort des Servers" reingeschoben wird. Das Client VI kümmert sich dann wieder darum, dass die Daten verschickt werden.
Ein paar Erfahrungen, die ich dabei gesammelt habe:
Es ist sinnvoll im Client VI eine Art Timeout zu implementieren, z.B. max. Lebensdauer des VIs - wenn keine Datenübertragung stattfindet - von 10 minuten => das hält den Speicher frei
Ich hab eine "ClientID" eingeführt, das war im Prinzip einfach eine Old Style Global, die bei jedem Start eines Clients VIs hochgezählt wurde. Die ID hab ich bei der Übergabe der Anfrage an die MainQ mitgeschickt, das ist ganz praktisch beim Debuggen, dann weiß man gleich, von welchem Client das stammt
die TCP/IP kommunikation hab ich nach dem Prinzip: vorweg 4 Byte, danach die Daten aufgebaut, wie im Example findert. Das ist die einfachste Methode dem Server mitzuteilen, wieviel Daten man denn nun tatsächlich schickt.
Für die Server-Anfragen (="Befehle") hab ich einen Cluster aufgebaut, aus einem Enum, und einem String, in den ich die Daten flatte ...
Es sieht ähnlich wie bei mir aus, das einzige was ich nicht verstanden habe, wozu brauchst du für jeden Client eine eigene Queue in den VIs die die Anfragen von Clients über TCP/IP empfangen?
Ansonsten vielen Dank für deine ausführliche Antwort, eg
Was man bei TCP Verbindungen machen sollte ist eine art "Alive" Protokoll zu implementieren, sprich ddie Clienten die in der Tabelle stehen alle X Sekunden mit einem PONG einen PING bestätigen lassen. Bzw alle gesendeten Daten zu quitieren.
Ich würde mich ja gerne mit Dir geistig duellieren, aber ich sehe Du bist unbewaffnet.
--------------------
Der Vorteil von Klugheit ist, dass man sich dumm stellen kann. Das Gegenteil ist schwieriger.
--------------------
Damit immer mehr immer weniger tun können, müssen immer weniger immer mehr tun.
' schrieb:Was man bei TCP Verbindungen machen sollte ist eine art "Alive" Protokoll zu implementieren, sprich ddie Clienten die in der Tabelle stehen alle X Sekunden mit einem PONG einen PING bestätigen lassen. Bzw alle gesendeten Daten zu quitieren.
Warum denn das? Bei UDP gebe ich dir Recht. TCP-IP kriegt Verbindungsverluste sehr wohl mit.
Übrigens: NI's Modbus Server für TCP-IP hat eine Server-mehrere Clients Struktur:
' schrieb:Was man bei TCP Verbindungen machen sollte ist eine art "Alive" Protokoll zu implementieren, sprich ddie Clienten die in der Tabelle stehen alle X Sekunden mit einem PONG einen PING bestätigen lassen. Bzw alle gesendeten Daten zu quitieren.
' schrieb:Warum denn das? Bei UDP gebe ich dir Recht. TCP-IP kriegt Verbindungsverluste sehr wohl mit.
Übrigens: NI's Modbus Server für TCP-IP hat eine Server-mehrere Clients Struktur:
So ist es, das was ich jetzt noch einbauen will ist die Clients aus der Tabelle auszutragen, sobald die Verbindung aus irgendwelchen Gründen verloren geht. Noch will ich den Dispatcher als Client zu einem anderen Dispatcher zu verbinden zu können. Dazu will ich noch einen Dispatcher-Befehl einbauen "Get available topics" oder sowas, damit ich die Liste bekommen kann und sich subscriben kann. Das wird in der Zukunft zum Debuggen und Fernstreuerung des Programms verwendet. Ausserdem, wie schon gesagt andere Kommunikationsmethoden wie Queue, Notifier und User Events einbauen. Und wenn alles soweit ist, eine abstrahierte Bibliothek erstellen.
Es wird doch eine tolle Sache.
@VDB mit Modbus hatte ich bis jetzt noch nichts zu tun gehabt, aber schon viel davon gehört. Vielleicht muss ich mich mal damit auseinandersetzen.
eg
P.S. ganz vergessen, ich werde noch das TCP/IP Protokoll verbessern, 2 Sync Bytes hinzufügen, Paketlänge 2-Byte lang machen und, wahrscheinlich noch die Checksumme hintendranhängen. Problem besteht noch mit Befehlen, wenn ich diese als Enum-Typedef definiere, dann wird die PubSub Bibliothek projektabhängig sein und wenn ich die so wie jetzt vom Typ-String lasse, dann kann es mal passieren, dass die Befehle sich wiederholen, was zu komischen Effekten führen kann. Weiss jemand Rat?
' schrieb:So ist es, das was ich jetzt noch einbauen will ist die Clients aus der Tabelle auszutragen, sobald die Verbindung aus irgendwelchen Gründen verloren geht. Noch will ich den Dispatcher als Client zu einem anderen Dispatcher zu verbinden zu können. Dazu will ich noch einen Dispatcher-Befehl einbauen "Get available topics" oder sowas, damit ich die Liste bekommen kann und sich subscriben kann. Das wird in der Zukunft zum Debuggen und Fernstreuerung des Programms verwendet. Ausserdem, wie schon gesagt andere Kommunikationsmethoden wie Queue, Notifier und User Events einbauen. Und wenn alles soweit ist, eine abstrahierte Bibliothek erstellen.
Es wird doch eine tolle Sache.
@VDB mit Modbus hatte ich bis jetzt noch nichts zu tun gehabt, aber schon viel davon gehört. Vielleicht muss ich mich mal damit auseinandersetzen.
eg
P.S. ganz vergessen, ich werde noch das TCP/IP Protokoll verbessern, 2 Sync Bytes hinzufügen, Paketlänge 2-Byte lang machen und, wahrscheinlich noch die Checksumme hintendranhängen. Problem besteht noch mit Befehlen, wenn ich diese als Enum-Typedef definiere, dann wird die PubSub Bibliothek projektabhängig sein und wenn ich die so wie jetzt vom Typ-String lasse, dann kann es mal passieren, dass die Befehle sich wiederholen, was zu komischen Effekten führen kann. Weiss jemand Rat?
Hört und seht sich schon alles sehr gut an!
Modbus: ich meinte nur das Grundgerüst für die Kommunikation bei den Modbus-Treiber ist Server-Client(s). Als Protokoll kannst du ja alles verschicken, Modbus, PubSub, HTTP....
Checksumme brauchst du nicht, die packt TCP-IP selber schon hinten dran. Wozu brauchst du die Sync-Bytes?
Enum-Problem: was spricht denn dagegen einen Strict-Typedef zu benutzen? Du könntest eine LIB Datei machen mit den Funktionen und das Enum-Control außerhalb davon lassen.
VDB
29.10.2007, 10:27 (Dieser Beitrag wurde zuletzt bearbeitet: 29.10.2007 10:28 von eg.)
' schrieb:Hört und seht sich schon alles sehr gut an!
Modbus: ich meinte nur das Grundgerüst für die Kommunikation bei den Modbus-Treiber ist Server-Client(s). Als Protokoll kannst du ja alles verschicken, Modbus, PubSup, HTTP....
Umso interessanter, muss mal Zeit nehmen und sich damit beschäftigen
' schrieb:Checksumme brauchst du nicht, die packt TCP-IP selber schon hinten dran. Wozu brauchst du die Sync-Bytes?
Damit das Protokoll, wie ein gewöhnliches binäres Übetragungsprotokoll aussieht. Ich habe schon einige (vielleicht 10-15) gesehen, die sind alle ähnlich aufgebaut. Somit könnte man das Protokoll in der Doku beschreiben und jeder Entwickler, kann dann eine Software dazu schreiben.
' schrieb:Enum-Problem: was spricht denn dagegen einen Strict-Typedef zu benutzen? Du könntest eine LIB Datei machen mit den Funktionen und das Enum-Control außerhalb davon lassen.
Ich habe gerade gemerkt, dass wenn das Netzwerk-Kabel getrennt wird, merkt der Server und Client nichts davon, erst dann wenn ich was senden will. Wenn ich aber gerade am TCP Lesen bin, passiert kein Fehler. Kann das jemand bestätigen?
' schrieb:Ich habe gerade gemerkt, dass wenn das Netzwerk-Kabel getrennt wird, merkt der Server und Client nichts davon, erst dann wenn ich was senden will. Wenn ich aber gerade am TCP Lesen bin, passiert kein Fehler. Kann das jemand bestätigen?
Ok, die automatische Enfernung aus der Tabelle habe ich implementiert, diese funktioniert aber nur, wenn man den Client "beendet" ohne sich zuerst "unsubcriben" zu haben. Bei der physikalischen Trennung der Verbindng passiert nichts.