Newsgroup: it.comp.lang.delphi
Titolo: [OT?][Lungo] Dubbi su Realizzazione protocollo di comunicazione C.S. con notifica

Salve a tutti,
Sto scrivendo un'applicazione composta da un eseguibile principale (P) ed un
numero
n, variabile, di moduli (M).
Onig modulo risiede in una sua dll, ed esporta una serie di funzioni ben
note
utili a (P) per diversi scopi: Avvio, Installazione, Aggiornamento...
La comunicazione tra (P) e gli (M) avviene per mezzo del protocollo TCP/IP.
E' inoltre possibile la comunicazione tra due o più (M)!
All'avvio (P) effettua un bind su tutte le interfacce di rete, mettendosi in
ascolto
su di una porta ben nota.
Nella comunicazione tra due o più (M) e tra gli (M) e (P), possono venir
inviate alcune richieste che necessitano di una _notifica_.
Il mio problema che mi trovo ad affrontar è che non riesco a trovare una
soluzione _decente_ per la gestione delle notifiche.
Vi descrivo il funzionamento del protocollo di connessione/comunicazione
*** CONNESSIONE (M) --> (P) ***
1) Apertura canale di comunicazione, e collegamento ad un server.
2) Il client, all'atto della ricezione dell'evento di "Connessione
Avvenuta",
    dovrà rispondere con un pacchetto di tipo "tpIdentification".
    Eventualmente, passerà al Server anche l'ID dello Slot (SlotID) che gli
è stato
    riservato nell'elenco dei client connessi.
    Se tale ID è -1, allora il client non ha preferenze sullo slot.
3) Quando il server riceverà il pacchetto tpIdentification registrerà la
connessione
    del client, ed inserirà le informazioni utili a rintracciare detto
client (IdPeerThread).
    Tali informazioni, andranno inserite nello SlotID passato dal client,
posto che questo ID
    sia diverso da -1.
4) Quando un client si disconnette, il server invierà un messaggio in
Broadcast per notificare
 l'evento ai client restanti (se ci sono).
In altre parole, quando un (M) apre il canale di comunicazione verso (P),
riceve la notifica dell'avvenuta connessione.
A questo punto, invia un pacchetto per chiedere a (P) un identificatore
univoco.
Ciò è necessario perchè possono esistere in esecuzione più copie dello
stesso (M)
_sulla stessa macchina_!
Il problema della notifica, almeno quello più serio, sorge quando un dato
(M),
diciamo (M1), richiede l'avvio di un (M2).
Inoltre, (M1) vuole inviare un pacchetto a (M2).
(M1) per poter comunicare con (M2) ha 2 alternative:
1- Comunicazione per mezzo (P)
 - Rappresenta lo standard.
 - (M1) invia un paccetto a (P) che lo reindirizza a (M2).
2- Comunicazione diretta con (M2)
 - E' mia scelta se implementarla o meno.
Come fareste a notificare l'identificatore univoco, assegnato a (M2),
al modulo (M1) che ne ha richiesto l'avvio?
Consideriamo che (P) può ricevere un numero imprecisato e variabile
di pacchetti, con frequenza non nota.
Io l'ho pensata così:
1- Richiesta CON NOTIFICA
 Le richieste con notifica sono, a loro volta, classificabili in:
 1.1- Richiesta avvio modulo
  Questo tipo di richiesta è la più difficile da gestire.
  Infatti, non abbiamo alcun riferimento univoco per il modulo
  che intendiamo lanciare.
  Il client richiede l'avvio di un modulo con NOTIFICA.
  Il server aggiunge alla lista delle notifiche la richiesta attuale.
  Il server riserva uno slot e lo comunica al client.
  Il client lega lo slot ricevuto alla notifica che attende.
  Il server manda in esecuzione il modulo e gli comunica
  lo slot assegnato.
  Il modulo si connette al server specificando lo slot a
  lui riservato.
  Il server lo inserisce nella lista dei moduli connessi
  alla posizione richiesta (slot).
  Il server elabora la lista delle notifiche in attesa,
  ed informa il client che il modulo da lui richiesto
  si è collegato, ed è raggiungibile allo slot già
  specificato.
 1.2- Richiesta generica
  Questo tipo di richiesta prevede che sia già disponibile
  l'identificatore univoco del modulo con cui intendiamo
  comunicare.
2- Richiesta SENZA NOTIFICA
 - In questo caso, il server elabora la richiesta mentre il client, dopo
averla
   inviata, prosegue le sue normali operazioni.
Aggiungo, inoltre, che il programma (P) ha un DB in cui memorizza alcuni
dati.
Eventualmente, si può pensare di utilizzare il DB per le notifiche.
Spero di essere stato sufficientemente chiaro :)
Grazie in anticipo per il Vs aiuto.
Saluti,
Carmine Moleti

 TCP/IP.  
Questa cosa non l'ho capita, come fai a mettere un server o client TCP
in una DLL, chi la esegue?
Prova ad esporre la tua necessita' e non il problema che vuoi risolvere
in quanto ritengo tu abbia scelto la via sbagliata. Inoltre potrebbe
essere molto piu' efficente e semplice da implementare utilizzando un
protocollo applicazione (es SOAP).
Saluti
-- 
I'am what I'am, I do what I can

 protocollo applicazione (es SOAP).
Volentieri :)
Ho esposto il problema da risolvere in questi termini, semplicemente
perchè ho quasi tutto realizzato. A dire il vero, manca proprio la gestione
della notifica.
Anyway...
Quello che devo realizzare è un'"accentratore di servizi".
Trattasi di un eseguibile che offre un insieme minimo di applicazioni ed
utility generiche:
1- Block notes
2- Calcolatrice
3- Backup
4- Installazione/Upgrade dei moduli inclusi nell'applicazione.
...
Questo accentratore deve utilizzare un database per la memorizzazione di
alcune informazioni.
I "servizi" sono delle dll, non activex, semplici e classiche dll.
Esse esportano un'interfaccia minima comune a tutti i servizi (funzioni per
il lancio, registrazione ...).
I servizi devono avere la possibilità di comunicare, in qualche modo, con il
server (exe) e tra
di loro.
Alcune comunicazioni possono richiedere una notifica.
Es:
Un servizio chiede ad un altro di posizionarsi su di un determinato record
del database, e di inviare
notifica dello stato dell'operazione. (Operazione completata, fallita
ecc...)
Tra le informazioni che il server deve memorizzare nel suo database, ci sono
anche le operazioni
che i vari client compiono sui dati.
Ciò è necessario perchè l'applicazione potrebbe essere multiutente, e quindi
mi serve una traccia
di ciò che viene fatto dal singolo utente. (ciò viene gestito attualmente
dal database e dal server per
mezzo degli eventi di Interbase)
Possono esistere uno o più database utilizzati dall'applicazione.
Uno è sicuramente quello utilizzato dall'accentratore.
Gli altri sono specifici dell'applicazione rilasciata con l'accentratore.
Il server ed i client, devono avere la possibilità di comunicare con
un'applicazione Debugger (anche
remota).
Due (o più) server accentratori, possono girare su macchine diverse e/o
sulla stessa macchina.
Ho bisogno (in futuro), di avere la possibilità di far comunicare i vari
accentratori, locali e remoti,
tra di loro.
Spero di non aver tralasciato nulla e di essere stato sufficientemente
chiaro.
Grazie ancora per il Vs aiuto.
Saluti,
Carmine

 ed utility generiche:
[cut]
Sono sempre piu' convinto tu stia reinventando l'acqua calda.
Quello che stai realizzando non e' altro che un sistema ad architettura
n-Tier a 3 livelli.
Client <=> Middleweare <=> Accesso dati
Secondo me la scelta delle DLL non e' corretta, e non capisco bene come
un server possa "lanciare" una dll che risiede su un'altra macchina.
Inoltre dici che le DLL espongono servizi come Block Notes etc. ma come
fa una DLL ad esporre un servizio con GUI, oltretutto a chi lo espone,
se risiede su un server e tu lo chiami da un altra macchina.


 tra di loro.
E per questo *userai* TCP/IP...

 Dal server, è possibile lanciare uno o più client.
Ma allora server e client si trovano sulla stessa macchina?
Se è si puoi usare ben altro che connessioni tcp-ip se no spiegami come fai
a lanciare una dll su una macchina diversa!?
Forse vuoi dire che il client, anch'esso un exe, lancia dei moduli locali
che si trovano in dll a seconda dei comandi del server?

 se risiede su un server e tu lo chiami da un altra macchina.
Non è la dll ad avere il block notes etc.
(nel messaggio precedente ho scritto: " Quello che devo realizzare è
un'"accentratore di servizi".
Trattasi di un eseguibile che offre un insieme minimo di applicazioni ed
utility generiche:")
L'accentratore (forse sbaglio a chiamarlo server?!) ha queste "utility".
L'accentratore ha una GUI(!)

 E per questo *userai* TCP/IP...
L'idea è:
Visto che devo realizzare tutto il casotto per TCP/IP, perchè non
utilizzarlo
_anche_ per la comunicazione tra le dll ed il server?

 di instanziare la GUI ecc...
Quindi sia quello che tu definisci server (exe) che quello che tu definisci
client (dll)  si trovano sulla stessa macchina?

 che si trovano in dll a seconda dei comandi del server?
Ci riprovo :)
Il server ed i client risiedono sulla stessa macchina.
Su due macchine diverse, possono essere in esecuzione due server (con i
rispettivi client).
I due server possono avere la necessità di comunicare tra di loro.
Un client su di una macchina può richiedere al server della seconda macchina
di eseguire un altro client su quest'ultima.
Esempio:
Operatore1(O1) su Macchina1 (M1) sta lavorando sulla tabella "Anagrafica
Clienti".
Operatore2(O2) su Macchina2 (M2) sta lavorando sulla tabella "Ordini
Clienti".
Per qualche assurda ragione, O1 vuole che O2 veda l'anagrafica del cliente
su cui O1 sta
lavorando.
Da M1, parte un messaggio diretto a M2.
M2 apre il modulo Anagrafica Clienti.
M2 comunica a M1 che il modulo è stato caricato.
M1 chiede a M2 di inoltrare un messaggio al modulo appena caricato, in modo
tale
che esso si posizioni sul cliente che O1 sta utilizzando.
E' solo un esempio banale, senza senso (forse).
Questo, magari è meglio :)
Ci potrebbe essere, ad esempio, su M2 un dispositivo che rilevi
Pressione,Temperatura ed Umidità.
O1 vuole leggere questi valori.
M1 chiede a M2 di lanciare il moduo apposito e di fornirlgi questi dati.
Tutto mentre O2 sta facendo altre cose...

 di eseguire un altro client su quest'ultima.
[CUT]
Adesso è chiaro :)
Comunque non capisco perchè vuoi far comunicare exe e dll della stessa
macchina tramite tcp ip, posso capirlo per server su macchine diverse.

 macchina tramite tcp ip, posso capirlo per server su macchine diverse.
Semplicemente perchè, avendo la pappa (quasi) pronta sul tcp/ip e dovendolo
comunque utilizzare, preferisco usare un solo modo.
Le comunicazioni locali avvengono tramite loopback.

 comunque utilizzare, preferisco usare un solo modo.
mi riassumi i tuoi dubbi francamente non vedo grosse difficoltà

> mi riassumi i tuoi dubbi francamente non vedo grosse difficoltà
La cosa che mi perplime è la gestione delle notifiche ai messaggi.
Ogni client riceve, a seguito della connessione al server, un identificaore
univoco.
Perchè:
1- Possono esistere in esecuzione più client dello stesso tipo, e si rende
    necessario poterne indirizzare uno specifico, piuttosto che lavorare di
    broadcast.
Sia C1 il primo client, e C2 il secondo.
Sia P il server.
C1 chiede a P di avviare C2, perchè:
1- Ha bisogno che C2 esegua un determinato compito.
A tal proposito, C1 deve comunicare a C2 cosa vuole.
C1 _non_ può sapere come comunicare con C2 all'atto della
richiesta di avvio di C2, perchè _non_ è a conoscenza dell'id
univoco assegnato da P a C2.
Quindi:
1. C1 chiede a P di avviare C2, e di avvisarlo quando C2 è in funzione.
2. P avvia C2 e gli assegna un id univoco.
3. P notifica C1 che C2 è raggiungibile tramite l'id: xxx@yyy
Come si può gestire in maniera semplice tutto ciò, considerando che,
 P potrebbe essere bombardato di messaggi in maniera imprevedibile?
Attualmente, ho messo in piedi un mezzo casino.
Tutto ciò mi ha fatto accidentalmente trascurare la possibilità che
sia (nell'esempio di cui sopra), lo stesso C1 ad assegnare a C2 (per mezzo
di P)
un id univoco.
In questo modo C1 saprebbe a priori come raggiungere C2.
Consigli e suggerimenti sono ben accetti.

 un id univoco.
lo eviterei.


Ciao anche a te.
Mi sono perso nei meandri delle tue specifiche, però mi sento di
consigliarti di dare un'occhiata a ASTA 
www.astatech.com
 , a RemObjects
www.remobjects.com
 e KbmMW 
www.components4developers.com
Saluti
Gello

 lo eviterei.
Perchè?

 Perchè?
Maggiore chiarezza delle comunicazioni.