2012-08-25 2 views
0

나는 하스켈을 상당히 잘 알고 있으며, 나는 봇용 IRC 인터페이스를 작성하고있다. 코드를 실행 한 후Haskell IRC Bot 스톨 아웃

..

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" 

I 도착 터미널에서 다음과 같은 출력 : 나는 다음과 같은 문제가

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 클라이언트가 잘 작동합니다. 도움을 주시면 감사하겠습니다.

+0

simpleirc : http://hackage.haskell.org/package/simpleirc – Anonymous

+0

글쎄, 나는 simpleirc를 사용하기로 결정했다 .... 나는 정말로 기술에 관심이 없다. 그러나, 나는 내 연결에 어떤 문제가 있는지 알고 싶습니다! – MagneticDuck

답변

2

hPrint 대신 hPutStr을 사용하면 \r\n이 렌더링되어 서버로 올바르게 전송됩니다. hPrint은 원하는 출력이 아닌 show과 같은 출력을 제공합니다. 최근에 나만의 IRC Bot 페이지를 만들면서 로봇을 만들었고 hPrintf을 사용했습니다.

hPutStrLn은 자동으로 문자열에 \n을 추가하므로 원하지 않는 경우 write에 넣지 않아도됩니다.

또한이 비트를 변경해야합니다.

return $ Bot { socket = h } 

귀하의 기능은 Handle을 반환하도록되어 있지만, 당신은 당신이 정의하지 않은 Bot를 반환하고 있습니다. return h으로 변경하면 정상적으로 처리됩니다. (컴파일 했으니 고정되어 있다고 가정합니다.)

2

100 % 확신 할 수는 없지만 연결될 때 클라이언트가 너무 빨리 작동하고있는 것으로 의심됩니다.

IRC 서버는 보내는 명령에 응답해야하지만 그렇지 않습니다. IRC 서버가 ERROR 행을 보내는 사실은 연결 문제가 아니라는 것을 나타내지 만 클라이언트가 프로토콜에 따라 작동하지 않기 때문에 IRC 서버가 연결을 끊습니다.

코드가 세 줄을 보내기 전에 IRC 서버가 데이터 보내기를 기다리는 지 확인하십시오.

+0

이제 코드를 편집하여 'run'함수가 세 개의 명령을 보내기 전에 서버가 세 개의 메시지를 보낼 때까지 대기합니다. 그러나 문제는 계속됩니다. – MagneticDuck

+0

@MagneticDuck 질문을 업데이트 된 코드로 업데이트하십시오. –

-1

ummm 문제는 포트 번호가 irc.freenode.net의 경우 8001이 아니고 irc.freenode.org의 경우 6667이어야한다는 것입니다. .