views:

128

answers:

6

I'm currently making a IRC bot in Java (I know, there are frameworks out there) and I'm trying to have it connect to multiple servers. The problem I'm having with this is not the connecting part, I'm just running my Connect class in x amount of threads. Each thread will connect the bot to the server/port specified. Now my problem is that when certain text is outputted by a user the bot is supposed to message the channel saying "you typed this command" (for an example). Now I would want the bot to message ALL servers saying "you typed this command". This is simply just an example (which is why it doesnt make much sense).

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();

Now having the example code above, I would want one thread to talk to the other when certain text is typed. Something like:

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

If anyone could help, I'd greatly appreciate it. Thanks!

A: 

The simplest solution is to pass a common object to both threads. In this case it might just be a String. For example:

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();

You're other example then becomes:

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

Each thread then should constantly check messagePasser to see when it changes and then output the message. This is obviously a very simple suggestion and completely bypasses many concerns about synchronization and thread safety.

EDIT: In light of learning that Strings are passed by value (learn something new every day...), You would merely have to create a simple MessagePasser object that encapsulates a String and any other data you would want.

Poindexter
+2  A: 

I think a simple approach would be an Observer pattern where each thread knows about all the other threads

Tommy
A: 

The messagePasser solution will not work because string objects in java are passed by value, not by reference.

bjoern.bauer
Good observation but please make this a comment to that answer and then delete this. Thanks and welcome to SO!
Paul Sasik
I tried but couldn't find out how. After reading the faq I realized that I need at least 50 reputation points to leave comments on posts that were not created by me.
bjoern.bauer
A: 

From your description I take that each of the threads is waiting for a message from some other user on the chat. Waiting means it calls some network method which returns only when a message arrives. As soon as that message arrives, the thread (optionally) generates an answer, posts it and then continues waiting. That why you have multiple threads, right?

That means, however, that threads can only send something after they received something. Because only then they are woken up from their waiting state. That means that it's not workable to "broadcast" the command response to all the threads. Instead, the receiving thread has to send it to all the servers (while the other threads are still waiting to read from these servers).

In other words: break up the strict assignment of servers to threads. Let any thread send to any server.

Wolfgang
A: 

Add each thread to a collection, say list and watch for the updates. As soon as an update is available, dispatch that to each thread. (Sounds like an observer...) !

Nrj
A: 

You should give each thread a Queue of incoming messages that other threads can push to in an asynchronous manner; java.util.concurrent.ConcurrentLinkedQueue would probably be a good class to use for that.

You will then need a single MessageSender class instance that has references to all your threads. If a thread wants to send a message to all other threads, it would call send(msg) on this global MessageSender object, and it in turn will then iterate over all threads and push the message to their respective queues (skipping the thread of the sender).

The threads themselves can then check their own queue from time to time (depending on whatever other logic they may be executing as well) and remove messages once they have handled them.

Luke Hutteman