2010-10-29 16 views
7

Attualmente sto facendo un bot IRC in Java (lo so, ci sono framework là fuori) e sto cercando di collegarlo a più server. Il problema che sto avendo con questo non è la parte di connessione, sto solo eseguendo la mia classe Connect in x quantità di thread. Ogni thread collegherà il bot al server/porta specificato. Ora il mio problema è che quando un certo testo viene emesso da un utente, il bot dovrebbe mandare un messaggio al canale dicendo "hai digitato questo comando" (per un esempio). Ora vorrei che il bot visualizzasse TUTTI i server dicendo "hai digitato questo comando". Questo è semplicemente un esempio (che è il motivo per cui non ha molto senso).Come avere due thread in conversazione tra loro?

Connect f = new Connect(irc.freenode.net, 6667); 
Thread ft = new Thread(f); 
ft.start(); 
Connect q = new Connect(irc.quakenet.org, 6667); 
Thread qt = new Thread(q); 
qt.start(); 

Ora avendo il codice di esempio sopra, vorrei che un thread parlasse all'altro quando si digita un determinato testo. Qualcosa di simile:

if (lineReader.substring(lineReader.indexOf(":"), lineReader.length()).equals("hello")) { 
    message both servers "Hello World!" 
} 

Se qualcuno potesse aiutare, lo apprezzerei molto. Grazie!

risposta

1

È necessario assegnare a ogni thread una coda di messaggi in arrivo che altri thread possono inviare in modo asincrono; java.util.concurrent.ConcurrentLinkedQueue sarebbe probabilmente una buona classe da usare per questo.

Avrai quindi bisogno di una singola istanza di classe MessageSender che abbia riferimenti a tutti i tuoi thread. Se un thread vuole inviare un messaggio a tutti gli altri thread, invierà send (msg) su questo oggetto MessageSender globale e, a sua volta, itererà su tutti i thread e invierà il messaggio alle rispettive code (saltando il thread del thread mittente).

I thread stessi possono quindi controllare la propria coda di volta in volta (a seconda di qualsiasi altra logica che potrebbero essere in esecuzione) e rimuovere i messaggi dopo averli gestiti.

+0

All'inizio ero riluttante a questo approccio, ma è sicuramente il più facile/efficace da implementare. Grazie: D – zamN

0

La soluzione più semplice è passare un oggetto comune a entrambi i thread. In questo caso potrebbe essere solo un String. Per esempio:

String messagePasser; 
Connect f = new Connect(irc.freenode.net, 6667, messagePasser); 
Thread ft = new Thread(f); 
ft.start(); 
Connect q = new Connect(irc.quakenet.org, 6667, messagePasser); 
Thread qt = new Thread(q); 
qt.start(); 

vostro altro esempio diventa quindi:

if (lineReader.substring(lineReader.indexOf(":"), lineReader.length()).equals("hello")){ 
    messagePasser = "Hello, World!"; 
} 

Ogni thread allora dovrebbe controllare costantemente messagePasser per vedere quando cambia e poi in uscita il messaggio. Questo è ovviamente un suggerimento molto semplice e ignora completamente molte preoccupazioni relative alla sincronizzazione e alla sicurezza dei thread.

EDIT: Alla luce di apprendimento che String s sono passati per valore (imparare qualcosa di nuovo ogni giorno ...), Si potrebbe semplicemente avere per creare un semplice MessagePasser oggetto che incapsula un String e qualsiasi altro dato che si vorrebbe.

+0

Quindi stai dicendo che mentre ascolto determinati comandi dal server dovrei anche ascoltare per vedere se la var cambia dalla versione perversa e se lo fa, la butterei su entrambi i server. Mi piace questa idea ma ciò richiederebbe di avere un po 'di tempo all'interno di un po' e non sono sicuro di quanto sia affidabile. – zamN

3

ritengo un approccio semplice sarebbe un Observer pattern dove ciascun thread conosce tutti gli altri thread

0

La soluzione messagePasser non funzionerà perché gli oggetti stringa in Java sono passati per valore, non per riferimento.

+1

Buona osservazione ma si prega di rendere questo un commento per quella risposta e quindi eliminare questo. Grazie e benvenuti a SO! –

+0

Ho provato ma non ho potuto scoprire come. Dopo aver letto le faq ho capito che ho bisogno di almeno 50 punti reputazione per lasciare commenti su post che non sono stati creati da me. –

0

Dalla tua descrizione prendo che ciascuno dei thread è in attesa di un messaggio da un altro utente sulla chat. Attendere significa chiamare un metodo di rete che ritorna solo quando arriva un messaggio. Non appena arriva il messaggio, il thread (facoltativamente) genera una risposta, lo inserisce e quindi continua ad attendere. Questo perché hai più thread, giusto?

Ciò significa, tuttavia, che i thread possono inviare qualcosa solo dopo aver ricevuto qualcosa. Perché solo allora vengono svegliati dal loro stato di attesa. Ciò significa che non è possibile "trasmettere" la risposta del comando a tutti i thread. Invece, il thread ricevente deve inviarlo a tutti i server (mentre gli altri thread sono ancora in attesa di leggere da questi server).

In altre parole: suddividere il severo compito dei server sui thread. Lasciare qualsiasi thread inviare a qualsiasi server.

+0

Vedi stavo pensando di farlo, ma rende il mio codice non flessibile ... del tutto, e questo mi spaventa. Mi piace troppo il codice flessibile: x. – zamN

0

Aggiungere ogni thread a una raccolta, pronunciare l'elenco e controllare gli aggiornamenti. Non appena è disponibile un aggiornamento, invialo a ogni thread. (Sembra un osservatore ...)!

Problemi correlati