Haskell IRC Bot停止运行

Haskell IRC Bot停止运行,haskell,bots,irc,Haskell,Bots,Irc,我非常了解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

我非常了解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"
主模块(Main),其中
导入网络
导入数据。列表
导入系统.IO
server=“irc.freenode.org”
端口=6667
chan=“#tanuki”
nick=“DuckBot01”
main::IO()
main=do
bot-hFlush stdout
putStrLn“完成”
A.
运行::句柄->IO()
运行h=do
写h“NICK”NICK
写h“用户”(尼克++“0*:教程机器人”)
写h“JOIN”chan
听着,h
--
--处理来自服务器的每一行
--
侦听::句柄->IO()
听h=永远$do
永远
清洁=下降1。dropWhile(/=':')。下降1
ping x=“ping:`isPrefixOf`x
pong x=写h“pong”(“:”:放下6个x)
eval::Handle->String->IO()
eval h“!quit”=写入h“quit”“:byebye”
eval=return()--忽略其他所有内容
privmsg::Handle->String->IO()
privmsg h s=写入h“privmsg”(chan++:“++s)
写入::句柄->字符串->字符串->IO()
写入句柄s t=do
hPrint句柄$s++++++++t++“\r\n”
putStrLn$“>”++s++++++++++++++++“\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
通过TestRing-0.9.2.1加载包。。。链接。。。完成。
加载包变压器-0.2.2.0。。。链接。。。完成。
正在加载程序包mtl-2.0.1.0。。。链接。。。完成。
正在加载包数组-0.4.0.0。。。链接。。。完成。
加载包deepseq-1.3.0.0。。。链接。。。完成。
正在加载程序包文本-0.11.1.13。。。链接。。。完成。
正在加载包parsec-3.1.2。。。链接。。。完成。
正在加载unix-2.5.1.0包。。。链接。。。完成。
加载包网络-2.3.0.10。。。链接。。。完成。
正在连接到irc.freenode.org。。。
完成。
>尼克·达克博特01
>用户DuckBot01 0*:教程机器人
>加入#塔努基
:cameron.freenode.net注意*:***正在查找您的主机名。。。
:cameron.freenode.net通知*:***正在检查标识
:cameron.freenode.net注意*:***找到了您的主机名
:cameron.freenode.net通知*:***无识别响应
错误:关闭链接:127.0.0.1(连接超时)
***异常::hGetLine:文件结束

为什么会超时?这不是我的连接,我的普通IRC客户端工作正常。非常感谢您的帮助。

不是100%确定,但我怀疑您的客户在连接时动作太快

IRC服务器应该响应您发送的命令,但事实并非如此。IRC服务器向您发送错误行的事实也表明这不是连接问题,但IRC服务器正在断开您的连接,因为您的客户端没有按照协议运行


请尝试确保在代码发送三行数据之前等待IRC服务器开始发送数据。

使用
hPutStr
而不是
hPrint
,以便正确呈现
\r\n
并将其发送到服务器
hPrint
将提供与
show
相同的输出,这不是您想要的。我最近也在Roll Your Own IRC bot页面上制作了一个bot,我坚持使用
hPrintf

hPutStrLn
会自动将
\n
附加到字符串中,因此,如果您不想这样做,则无需将其添加到
write

另外,你应该改变这一点

return $ Bot { socket = h }

您的函数应该返回一个
句柄
,但您返回的是一个尚未定义的
Bot
。只需将其更改为
return h
,您在那里就可以了。(因为您需要编译它,我假设您已经修复了它。)

嗯,这里的问题是它连接到的端口对于irc.freenode.net应该是8001,而对于irc.freenode.org应该是6667

我编辑了代码,所以现在“run”函数等待服务器发送三条消息,然后再发送三条命令。但是,问题仍然存在。@MagneticDuck请使用更新的代码simpleirc更新您的问题:好吧,我决定使用simpleirc。。。。我真的对技术不感兴趣。然而,我想知道我的连接出了什么问题!