I've worked my way through Don Stewart's Roll your own IRC bot tutorial, and am playing around with some extensions to it. My current code is essentially the same as the "The monadic, stateful, exception-handling bot in all its glory"; it's a bit too long to paste here unless someone requests it.
Being a Comcast subscriber, it's particularly important that the bot be able to reconnect after periods of poor connectivity. My approach is to simply time the PING
requests from the server, and if it goes without seeing a PING
for a certain time, to try reconnecting.
So far, the best solution I've found is to wrap the hGetLine
in the listen
loop with System.Timeout.timeout
. However, this seems to require defining a custom exception so that the catch
in main
can call main
again, rather than return ()
. It also seems quite fragile to specify a timeout value for each individual hGetLine
.
Is there a better solution, perhaps something that wraps an IO a
like bracket
and catch
so that the entire main can handle network timeouts without the overhead of a new exception type?
How about running a separate thread that performs all the reading and writing and takes care of periodically reconnecting the handle?
Something like this
input :: Chan Char
output :: Chan Char
putChar c = writeChan output c
keepAlive = forever $ do
h <- connectToServer
catch
(forever $
do c <- readChan output; timeout 4000 (hPutChar h c); return ())
(\_ -> return ())
The idea is to encapsulate all the difficulty with periodically reconnecting into a separate thread.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With