2010-10-29 53 views
7

我目前正在Java中製作一個IRC bot(我知道,那裏有框架),我試圖讓它連接到多個服務器。我遇到的問題不是連接部分,我只是在x個線程中運行Connect類。每個線程都會將bot連接到指定的服務器/端口。現在我的問題是,當用戶輸出某些文本時,機器人應該通知「你輸入了這個命令」(例如)。現在我想讓機器人向所有服務器發送消息,告訴你「你輸入了這個命令」。這僅僅是一個例子(這就是爲什麼它沒有多大意義)。如何讓2個主題相互交談?

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

現在具有上面的示例代碼,我想讓一個線程在輸入某些文本時與另一個線程對話。例如:

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

如果有人可以幫忙,我將不勝感激。謝謝!

回答

1

您應該給每個線程一個其他線程可以以異步的方式推入的傳入消息的隊列; java.util.concurrent中。ConcurrentLinkedQueue可能是一個很好的類。

然後,您將需要一個MessageSender類實例,它引用了所有線程。如果一個線程想要向所有其他線程發送一條消息,它會在這個全局MessageSender對象上調用send(msg),然後它將遍歷所有線程並將消息推送到它們各自的隊列(跳過發送者)。

線程本身可以隨時檢查自己的隊列(取決於它們可能正在執行的任何其他邏輯),並在處理完消息後刪除它們。

+0

起初我對這種方法猶豫不決,但它絕對是最容易/最有效的實施。感謝:D – zamN 2010-11-01 05:50:44

0

最簡單的解決方案是將一個公共對象傳遞給兩個線程。在這種情況下,它可能只是一個String。例如:

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

你的其他例子就變成了:

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

每個線程則應該不斷地檢查messagePasser時看到它的變化,然後輸出信息。這顯然是一個非常簡單的建議,完全繞過了許多關於同步和線程安全性的擔憂。

編輯:在得知String s的值傳遞的光(每天學習新的東西......),你會只需要創建一個簡單的MessagePasser對象封裝了String,你需要的任何其他數據。

+0

那麼你是說,在從服務器偵聽某些命令的同時,我還應該聽取看看var是否從前面的版本改變,如果它發生了變化,那麼我會將它發送給兩臺服務器。我喜歡這個想法,但這需要我在一段時間內有一段時間,我不確定那是多麼可靠。 – zamN 2010-11-01 01:00:16

3

我認爲一個簡單的方法是一個Observer pattern其中每個線程都知道所有其他線程

0

因爲在Java String對象是按值傳遞,而不是引用的messagePasser解決方案將無法工作。

+1

良好的觀察,但請讓這個評論回答,然後刪除它。謝謝,歡迎來到SO! – 2010-10-29 17:23:47

+0

我試過,但無法找出如何。閱讀常見問題後,我意識到我需要至少50個聲望點才能對未由我創建的帖子發表評論。 – 2010-10-29 17:30:11

0

從您的描述中,我認爲每個線程正在等待來自聊天中某個其他用戶的消息。等待意味着它會調用一些只在消息到達時才返回的網絡方法。一旦該消息到達,線程(可選)生成一個答案,發佈它,然後繼續等待。那爲什麼你有多個線程,對吧?

然而,這意味着,線程只能收到一些東西后才能發送。因爲只有這樣他們才能從等待的狀態中醒來。這意味着將命令響應「廣播」到所有線程是不可行的。相反,接收線程必須將其發送到所有服務器(而其他線程仍在等待從這些服務器讀取)。

換句話說:分解嚴格的服務器分配給線程。讓任何線程發送到任何服務器。

+0

看到我正在考慮這樣做,但它只是讓我的代碼不靈活...而且這讓我很害怕。我太喜歡靈活的代碼:x。 – zamN 2010-11-01 01:05:11

0

將每個線程添加到集合中,比如列表中,並查看更新。只要有更新可用,就將其分發給每個線程。 (聽起來像一個觀察者...)!