
Yeah I ended up doing pretty much what they do. The problem was I thought I
could collect all the IO actions one by one into an array and then just map
some other IO action over the array, but apparently the IO monad doesn't
like being lazy.
What you end up having to do is do one IO action at a time, getting the udp,
then sending it over the tchan immediately before attempting to fetch the
next udp packet. I ended up with:
fetchUDPSIP :: TChan a -> TChan B.ByteString -> IO ()
fetchUDPSIP commands chan = do
sock <- getUDPSocket 5060
forever $ getUDP sock >>= atomically . writeTChan chan
Which is perfectly fine. Thanks.
On Mon, Jul 19, 2010 at 1:50 PM, aditya siram
Have you looked at the Real World Haskell example [1] for reading from a UDP socket? In the inner "procMessages" the authors seem to show how to read one packet at a time without using unsafePerformIO.
-deech
[1] http://book.realworldhaskell.org/read/sockets-and-syslog.html in the section marked "UDP Syslog Server"
I am writing a voip server to take advantage of haskells awesome
On Mon, Jul 19, 2010 at 9:07 AM, David McBride
wrote: threading and parsing ability. At first everything was going great, but my thread that fetches udp makes use of unsafePerformIO:
fetchUDPSIP :: TChan B.ByteString -> IO () fetchUDPSIP chan = do sock <- getUDPSocket 5060 let results = (unstrict . repeat . getUDP) sock mapM_ (atomically . writeTChan chan) results where unstrict [] = [] unstrict (x:xs) = unsafePerformIO x:unstrict xs
It fetches it from a socket, and then writes it to a TChan. This results in a stream of bytestrings that another thread can read from. If I don't use unsafePerformIO, then it tries to read all possible packets before returning anything, and so it never writes to the TChan at all. The problem with doing it this way is that unsafePerformIO apparently stops every other thread from doing anything while it is waiting for a packet.
But I can't think of a way to rewrite this function to do what I want. I'm kind of new to this, does anyone have any hints that could help me out?
Here's a simple version without any of the implementation details:
fetchLine = do let results = (unstrict . repeat) getLine mapM_ putStrLn results where unstrict [] = [] unstrict (x:xs) = unsafePerformIO x:unstrict xs
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners