Newsgroup: it.comp.java
Titolo: Interazione tra WS e servlet

Ciao, ho un problema abbastanza complesso: ho deployato un semplice web
service che si appoggia ad axis su jboss. Fin qui tutto ok. Ora ho un
client che richiede un metodo del ws: il ws mette in attesa questo
client, aspetta un evento e risponde al client. L'evento però è
generato da una servlet, ovvero è un utente che interagendo con il
sistema fa scatenare l'evento. Come fa una servlet a avvertire il ws
dell'azione dell'utente?
Avevo pensato ad un Observer, ma non so come far comunicare la servlet
con il ws....
Qualche idea?

potresti fare un metodo new web service seganaEvento()
che verra richiamato dalla servlet....
il thread che serve il client fara' cosi (grosso modo)
syncronized(this)
{
    this.wait();
}
mentre il metodo segnalaEvento farà cosi:
syncronized(this)
{ 
   this.notifyAll();
}
Spero di averti aiutato!

Grazie del suggerimento stefano, mi sembra un'ottima idea. Il fatto è che
però la servlet che segnala un'evento deve anche passare un messaggio. Ad
esempio l'esempio che potrebbe segnalare è: "Play risorsaXY
altri_parametri". Con la notify non credo che si possano passare
parametri... credi che si possa fare in qualche modo? L'alternativa era
implementare una struttura client/server tra servlet e WS, ma la trovo
macchinosa e meno elegante...
Alberto


beh, passare un messaggio dovrebbe essere semplice, nel metodo
segnalaEvento ci passi un parametro di tipo String!

Uhm...dunque ho riflettuto un po' sulla questione: il fatto è che di
client che fanno una richiesta al WS ce ne sono diversi
contemporaneamente. L'utente vuole eseguire un "Play" su un client in
particolare.
Con notifyAll() tutti i thread vengono a sapere che si è verificato
l'evento, ma come faccio a sapere quale evento è? Tu dici di passare un
parametro al metodo che fa la notifyAll, ma non ho ben capito come fa quel
thread a passare il parametro algi altri.
Quello che mi servirebbe è:
-tutti i thread (WS) che stanno servendo un client sono in attesa di un
evento.
-l'utente tramite la servlet genera l'evento, in paricolare "clientX Play
risorsaY"
-il thread che sta servendo il clientX (e solo lui) invia a clientX la
risposta "Play risorsaY"
Un qualcosa del genere....
Alberto

mmmh....potresti fare cosi: crei una variabile risorse di tipo map...e
un arrayList
il client che serve X potrebbe fare cosi:
syncronized(this) {
   set.add(X); // set è di tipo insieme(cioe un elemento non viene
inserito se esiste gia). viene usato per condividere X
}
Object x = set.get(X);
syncronized(x)
{
    if(risorse.get(X) == null) x.wait();
  Object risorsa = risorse.get(X);  // quando sono qua, risorsa
disponibile
}
il metodo in attesa della sevlet sarà cosi fatto:
public void sveglia(String X, String Y)
{
   syncronized(this) {
       set.add(X); // set è di tipo insieme
   }
   Object x = set.get(X);
   syncronized(x)
   {
       risorse.put(X,Y);
       x.notify();
   }
}
Spero di essermi spiegato!

Ciao stefano, dunque credo di aver capito il senso del codice, potresti
spiegarmi meglio qualche dettaglio? Intanto faccio confusione tra set e
map: nel codice parli di entrambi, intendi la stessa cosa? Perchè a
volte leggo set.get, altre risorse.get (risorse dicevi che era un
map...).
Grazie mille per l'interessamento, mi è utilissimo!
Alberto

Dunque forse in parte riesco a rispondermi da solo. risorse (io l'ho
chiamato "comandi") è una Map (ho visto che Map è una interfaccia,
implementata ad esempio da HashMap, che sto provando ad usare), che
contiene coppie <destinatario,comando> (che tu chiami X,Y). Il Set
invece è un insieme dove vengono messi tutti i client connessi al WS,
in modo tale da poter prendere un riferimento ad essi per farci sopra
wait() e notify()  (in questo caso sono usati per implementare una
sorta di Monitor se non ricordo male i concetti sulla concorrenza...).
Ho interpretato bene?
L'unico problema è che i Set non hanno un metodo di get()...magari
posso provare con una LIst o qualcosa del genere.

Per la cronaca, qualora dovesse servire a qualcuno, la soluzione
dovrebbe essere all'incirca questa:
public class SalutoWS
{
	public HashMap<String, String> comandi = new HashMap<String,
String>();
	public Set<String> set = new HashSet<String>();
	public String richiediComando(String X)
	{
		Iterator iter;
		synchronized(this)
		{
			set.add(X); // set è di tipo insieme(cioe un elemento non viene
			   			// inserito se esiste gia). viene usato per condividere X
		}
		Object x = new Object();
		Object comando = new Object();
		iter = set.iterator();
		while(iter.hasNext())
		{
			x = iter.next();
			if(x.equals(X))
				break;
		}
		synchronized(x)
		{
			if(comandi.get(X) == null)
				try{
					x.wait();	// aspetta che arrivi un comando
				}catch(InterruptedException ie){}
		    comando = comandi.remove(X);  // quando sono qua, comando
disponibile, lo prendo ed elimino dall'hashmap
		}
		return comando.toString();
	}
	public String sveglia(String modulo, String comando)
	{
		String esito = "OK";
		synchronized(this)
		{
			set.add(modulo); // set è di tipo insieme
		}
		Object x = new Object();
		Iterator iter= set.iterator();
		/* cerca in set il modulo X */
		while(iter.hasNext())
		{
			x = iter.next();
			if(x.equals(modulo))
				break;
		}
		synchronized(x)
		{
			comandi.put(modulo, comando);
			x.notify();
		}
 
		return esito;
	} 
 
}
Alberto

Esatto, era esattamente cio che intendevo dire!
Spero che ti funzioni!

Si stefano, sembra funzinare, grazie mille per la dritta! ;-)