0

私はHaskellをかなりよく知っており、ボット用のIRCインターフェースを書いています。私は次の問題を抱えています:

コードを実行した後。

module Main (main) where

import Network
import Data.List
import System.IO

server = "irc.freenode.org"
port   = 6667
chan   = "#tanuki"
nick   = "DuckBot01"

main :: IO ()
main = do
    bot <- connect 
    run bot

connect :: IO Handle
connect = notify $ do
    h <- connectTo server (PortNumber (fromIntegral port))
    hSetBuffering h NoBuffering
    return $ Bot { socket = h }
  where
    notify a = do
        putStrLn ("Connecting to " ++ server ++ " ... ") >> hFlush stdout
        putStrLn "done."
        a

run :: Handle -> IO () 
run h = do
    write h "NICK" nick
    write h "USER" (nick++" 0 * :tutorial bot")
    write h "JOIN" chan
    listen h 
--
-- Process each line from the server
--
listen :: Handle -> IO ()
listen h = forever $ do
    s <- init `fmap` hGetLine h
    putStrLn s
    if ping s then pong s else eval h (clean s)
  where
    forever a = a >> forever a
    clean     = drop 1 . dropWhile (/= ':') . drop 1
    ping x    = "PING :" `isPrefixOf` x
    pong x    = write h "PONG" (':' : drop 6 x)

eval :: Handle -> String -> IO ()
eval     h "!quit"               = write h "QUIT" ":byebye" 
eval     _ _                     = return () -- ignore everything else

privmsg :: Handle -> String -> IO ()
privmsg h s = write h "PRIVMSG" (chan ++ " :" ++ s)

write :: Handle -> String -> String -> IO ()
write handle s t = do
    hPrint handle $ s ++ " " ++ t ++ "\r\n"
    putStrLn $ "> " ++ s ++ " " ++ t ++ "\n"

ターミナルで次の出力が得られます。

Loading package bytestring-0.9.2.1 ... linking ... done.
Loading package transformers-0.2.2.0 ... linking ... done.
Loading package mtl-2.0.1.0 ... linking ... done.
Loading package array-0.4.0.0 ... linking ... done.
Loading package deepseq-1.3.0.0 ... linking ... done.
Loading package text-0.11.1.13 ... linking ... done.
Loading package parsec-3.1.2 ... linking ... done.
Loading package unix-2.5.1.0 ... linking ... done.
Loading package network-2.3.0.10 ... linking ... done.
Connecting to irc.freenode.org ... 
done.
> NICK DuckBot01

> USER DuckBot01 0 * :tutorial bot

> JOIN #tanuki

:cameron.freenode.net NOTICE * :*** Looking up your hostname...
:cameron.freenode.net NOTICE * :*** Checking Ident
:cameron.freenode.net NOTICE * :*** Found your hostname
:cameron.freenode.net NOTICE * :*** No Ident response
ERROR :Closing Link: 127.0.0.1 (Connection timed out)
*** Exception: <socket: 8>: hGetLine: end of file

なぜタイムアウトするのですか?それは私の接続ではありません、私の通常のIRCクライアントは正常に動作します。ヘルプをいただければ幸いです。

4

3 に答える 3

2

100%確実ではありませんが、接続時にクライアントの動作が速すぎると思われます。

IRCサーバーは、送信するコマンドに応答する必要がありますが、応答しません。IRCサーバーがエラー行を送信するという事実は、それが接続の問題ではないことも示していますが、クライアントがプロトコルに従って動作していないため、IRCサーバーはあなたを切断しています。

コードが3行を送信する前に、IRCサーバーがデータの送信を開始するのを待つようにしてください。

于 2012-08-25T00:51:26.660 に答える
1

hPutStr代わりに使用hPrintする\r\nと、レンダリングされてサーバーに正しく送信されます。hPrintと同じ出力が得られますがshow、これは必要な出力ではありません。最近、Roll Your Own IRC Botページに続いてボットを作成しましたが、を使用し続けましたhPrintf

hPutStrLn文字列に自動的に追加\nされるので、それが必要でない場合は、文字列に追加する必要はありませwriteん。

また、このビットを変更する必要があります。

return $ Bot { socket = h }

関数はを返すことになっていますが、定義していないをHandle返しています。Botに変更するだけreturn hで大​​丈夫です。(コンパイルできるので、修正したと思います。)

于 2012-08-26T05:51:19.487 に答える
-1

ここでの問題は、接続先のポートがirc.freenode.orgの6667ではなくirc.freenode.netの8001である必要があることです。

于 2013-01-27T07:57:38.257 に答える