PDA

Visualizza la versione completa : Creare XML per scambio dati nella Intranet


VaLvOnAuTa
08-09-2006, 17:55
Salve :D

Quesito: Un'applicazione server (sviluppata da me) detiene una serie di informazioni sullo stato dei client connessi. Il capo vuole queste informazioni visualizzate sulla intranet (scritta in php). Come fare?
Semplice: basta far sì che ad ogni variazione di stato dei client il server scriva le informazioni su un file xml che sia accessibile dallo script php che andrà a leggerlo.

Ok, la teoria è semplice. E' sulla pratica che mi perdo :stordita:
Allora, il server crea il file xml se non lo trova, poi deve verificare se le informazioni dell'utente che si è connesso (identificato da un numero) sono già presente nel file xml.
Se lo sono modifica lo stato (se necessario)
se non lo sono, aggiunge un nodo con tutte le informazioni sul client.

Ok, dato che non sono ferratissimo sull'xml, che componente uso per fare tutto ciò? :fagiano:
C'è qualche esempio on-line consultabile?

alka
08-09-2006, 18:02
C'è il componente TXMLDocument, che incapsula il motore MS XML, oppure implementazioni gratuite come OpenXML (http://www.philo.de/xml/).

Se ti capita di provare quest'ultimo, dimmi cosa ne pensi, sono interessato. :)

Ciao! :ciauz:

VaLvOnAuTa
11-09-2006, 16:21
OK, fatto. Solo che adesso ho un dubbio atroce. Premetto che il file xml sarà formato così:

<?xml version="1.0" encoding="iso-8859-1"?>
<service>
<phones>
<phone interno="101">
<username>Fabrizio</username>
<status>1</status>
</phone>
</phones>
</service>Il client in pratica funziona così: legge una variazione di stato del telefono (ad esempio se riceve una chiamata, se sta per inviare una chiamata e così via) ed invia un record (che contiene interno, username e status) al server che esegue questo codice:

xmlDoc.FileName := path+'status.xml';
try
xmlDoc.Active := true;
ANode := xmlDoc.DocumentElement;
ANode := ANode.ChildNodes.FindNode('phones');
if (ANode <> nil) and (ANode.ChildNodes.Count > 0) then
begin
fh := 0;
found:= false;
repeat
begin
if ANode.ChildNodes[fh].Attributes['interno'] = l.number then
begin
found := true;
ANode.ChildNodes[fh].ChildNodes.FindNode('status').NodeValue :=l.status;
end
else
fh := fh+1;
end;
until (fh<=ANode.ChildNodes.Count) or (found=true);
if (found=false) then
begin
ANode := xmlDoc.DocumentElement;
ANode := Anode.ChildNodes.FindNode('phones');
ANode := ANode.AddChild('phone');
ANode.Attributes['interno'] := l.number;
ANode.AddChild('username').NodeValue := l.user;
ANode.AddChild('status').NodeValue := l.status;
end;
end
else
begin
ANode := xmlDoc.DocumentElement;
ANode := ANode.ChildNodes.FindNode('phones');
ANode := ANode.AddChild('phone');
ANode.Attributes['interno'] := l.number;
ANode.AddChild('username').NodeValue := l.user;
ANode.AddChild('status').NodeValue := l.status;
end;
except on e:exception do
WriteLog('Errore xml: '+E.Message);
end;
xmlDoc.SaveToFile(path+'status.xml');
xmlDoc.Active := false;In pratica, dopo aver caricato il contenuto del file "status.xml" esegue un clico per cercare se nel file è registrato il telefono con interno l.interno
Se lo trova modifica il campo status, altrimenti aggiunge un altro nodo con interno=l.interno
e tutte le informazioni contenute nel record.

Il problema è che con un unico client non ha problemi (aggiorna correttamente il nodo relativo all'interno associato al client). Già con due client (associati, ovviamente, a due interni differenti) lo status di un client viene aggiornato mentre quello del secondo viene aggiunto anche se già presente.
Premettendo che il server è in realtà un servizio windows (quindi già di per sè multithread), il problema potrebbe essere un accesso simultaneo dei due client al file xml? E se sì, come potrei fare a risolverlo?

alka
11-09-2006, 17:07
Direi che lo risolvi unicamente "serializzando" l'accesso al file XML e alla modifica dello stato del record specifico, in modo che uno solo possa effettuare tale operazione.

Esistono molteplici strumenti per gestire l'accesso concorrente a risorse: sezioni critiche, mutex, semafori, ...

Prova a fare una ricerca su Google usando le parole chiave di cui sopra (CriticalSection, Mutex, ...).

Ciao! :ciauz:

VaLvOnAuTa
11-09-2006, 18:03
Non so se comporterà, in futuro problemi di accesso alle risorse (il servizio dovrebbe essere threadsafe così come il componente IdTCPServer degli Indy).
So per certo che l'errore del messaggio precedente era dovuto ad uno stupido errore :fagiano:
La condizione dell'until era sempre vera e quindi non veniva eseguita la ricerca del secondo nodo :stordita:

Loading