私は Python で IRC ボットを作成しました。IRC コマンドを待機し、メッセージを呼び出し元の関数に返す方法を見つけようとしています。これらのものをゼロから作成することを学ぼうとしているなど、さまざまな理由で外部ライブラリの使用を拒否しています。また、既存のもののドキュメントをふるいにかけましたが、それらは包括的すぎます。シンプルなものを作ってみました。
例えば:
def who(bot, nick):
bot.send('WHO %s' % nick)
response = ResponseWaiter('352') # 352 - RPL_WHOREPLY
return response.msg
IRC メッセージを解析する Message クラスのオブジェクトを呼び出し元の関数に返します。
def check_host(bot, nick, host):
who_info = who(bot, nick)
if who_info.host == host:
return True
return False
私はリアクター パターン、オブザーバー パターンを調べ、これのために 100 の異なるイベント システム デザインを実装しようとしましたが、役に立ちませんでした。私は完全に迷っています。
解決策を提供するか、正しい方向に向けてください。これを行う簡単な方法が必要です。
だから私がやったことは、ボットのwhoメソッドから私のジェネレーター(ボットメソッド)からグラブメッセージを使用することです。ジェネレーターは次のようになります。
def msg_generator(self):
''' Provides messages until bot dies '''
while self.alive:
for msg in self.irc.recv(self.buffer).split(('\r\n').encode()):
if len(msg) > 3:
try: yield Message(msg.decode())
except Exception as e:
self.log('%s %s\n' % (except_str, str(e)))
これで、ボットの who メソッドは次のようになります。
def who(self, nick):
self.send('WHO %s' % nick)
for msg in self.msg_generator():
if msg.command == '352':
return msg
ただし、現在はメッセージを制御しているため、who メソッドに使用していないメッセージを適切なハンドラーに放棄する何らかの方法が必要です。
私のボットは通常、すべてのメッセージを次のように処理します。
def handle(self):
for msg in self.msg_generator():
self.log('◀ %s' % (msg))
SpaghettiHandler(self, msg)
そのため、ボットの who メソッドがジェネレーターを使用してメッセージを受信している間、私の SpaghettiHandler が処理するメッセージは処理されません。
それは機能しています..そして、メッセージを失うのが難しいほど十分に高速に機能します. しかし、ボットが同時に多くのコマンドを実行すると、これが問題になる可能性があります。この方向で解決策が見つかると確信していますが、関係のないメッセージを放棄するように設定していても、それが良い方法であるかどうかわからないため、これを答えとして作成しませんでしたリスナーに。