我非常了解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客户端工作正常。感谢帮助。
答案 0 :(得分:2)
不是100%肯定,但我怀疑你的客户在连接时行动太快。
IRC服务器应该响应您发送的命令,但事实并非如此。 IRC服务器向您发送ERROR行的事实也表明它不是连接问题,但IRC服务器正在断开您的连接,因为您的客户端没有根据协议行事。
尝试确保在代码发送三行之前等待IRC服务器开始发送数据。
答案 1 :(得分:1)
使用hPutStr
代替hPrint
,这样就可以呈现\r\n
并正确发送到服务器。 hPrint
将为您提供与show
相同的输出,这不是您想要的。我最近在滚动你自己的IRC Bot页面上制作了一个机器人,我坚持使用hPrintf
。
hPutStrLn
会自动将\n
附加到您的字符串中,因此如果您不想要的话,则无需将其添加到write
中。
另外,你应该改变这一点。
return $ Bot { socket = h }
您的函数应返回Handle
,但您返回的是您未定义的Bot
。只需将其更改为return h
,您就可以了。 (因为你已经编译了,我假设你修复了它。)
答案 2 :(得分:-1)
嗯,这里的问题是它连接的端口应该是irc.freenode.net的8001而不是irc.freenode.org的6667。