You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
122 lines
4.1 KiB
122 lines
4.1 KiB
|
14 years ago
|
{-# LANGUAGE PackageImports, OverloadedStrings #-}
|
||
|
|
module Example where
|
||
|
|
|
||
|
|
import Network.XMPP
|
||
|
|
import Control.Concurrent
|
||
|
|
import Control.Concurrent.STM
|
||
|
|
import Control.Monad
|
||
|
|
import Control.Monad.IO.Class
|
||
|
|
|
||
|
|
import Data.Maybe
|
||
|
|
import Data.Text (Text)
|
||
|
|
import qualified Data.Text as Text
|
||
|
|
import Data.XML.Pickle
|
||
|
|
import Data.XML.Types
|
||
|
|
|
||
|
|
import Network.XMPP.Pickle
|
||
|
|
|
||
|
|
import System.Environment
|
||
|
|
|
||
|
|
testUser1 :: JID
|
||
|
|
testUser1 = read "testuser1@species64739.dyndns.org/bot1"
|
||
|
|
|
||
|
|
testUser2 :: JID
|
||
|
|
testUser2 = read "testuser2@species64739.dyndns.org/bot2"
|
||
|
|
|
||
|
|
superviser :: JID
|
||
|
|
superviser = read "uart14@species64739.dyndns.org"
|
||
|
|
|
||
|
|
|
||
|
|
attXmpp :: STM a -> XMPPThread a
|
||
|
|
attXmpp = liftIO . atomically
|
||
|
|
|
||
|
|
testNS :: Text
|
||
|
|
testNS = "xmpp:library:test"
|
||
|
|
|
||
|
|
data Payload = Payload Int Bool Text deriving (Eq, Show)
|
||
|
|
|
||
|
|
payloadP = xpWrap (\((counter,flag) , message) -> Payload counter flag message)
|
||
|
|
(\(Payload counter flag message) ->((counter,flag) , message)) $
|
||
|
|
xpElem (Name "request" (Just testNS) Nothing)
|
||
|
|
(xpPair
|
||
|
|
(xpAttr "counter" xpPrim)
|
||
|
|
(xpAttr "flag" xpPrim)
|
||
|
|
)
|
||
|
|
(xpElemNodes (Name "message" (Just testNS) Nothing)
|
||
|
|
(xpContent xpId))
|
||
|
|
|
||
|
|
invertPayload (Payload count flag message) = Payload (count + 1) (not flag) (Text.reverse message)
|
||
|
|
|
||
|
|
iqResponder = do
|
||
|
|
(free, chan) <- listenIQChan Get testNS
|
||
|
|
unless free $ liftIO $ putStrLn "Channel was already taken"
|
||
|
|
>> error "hanging up"
|
||
|
|
forever $ do
|
||
|
|
next@(iq,_) <- liftIO . atomically $ readTChan chan
|
||
|
|
let payload = unpickleElem payloadP $ iqBody iq
|
||
|
|
let answerPayload = invertPayload payload
|
||
|
|
let answerBody = pickleElem payloadP answerPayload
|
||
|
|
answerIQ next answerBody
|
||
|
|
|
||
|
|
autoAccept :: XMPPThread ()
|
||
|
|
autoAccept = forever $ do
|
||
|
|
st <- pullPresence
|
||
|
|
case st of
|
||
|
|
Presence from _ idq (Just Subscribe) _ _ _ _ ->
|
||
|
|
sendS . SPresence $
|
||
|
|
Presence Nothing from idq (Just Subscribed) Nothing Nothing Nothing []
|
||
|
|
_ -> return ()
|
||
|
|
|
||
|
|
sendUser txt = sendS . SMessage $ Message Nothing superviser Nothing Nothing Nothing
|
||
|
|
(Just (Text.pack txt)) Nothing []
|
||
|
|
|
||
|
|
|
||
|
|
expect debug x y | x == y = debug "Ok."
|
||
|
|
| otherwise = do
|
||
|
|
let failMSG = "failed" ++ show x ++ " /= " ++ show y
|
||
|
|
debug failMSG
|
||
|
|
sendUser failMSG
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
runMain :: (String -> STM ()) -> Int -> IO ()
|
||
|
|
runMain debug number = do
|
||
|
|
let (we, them, active) = case number of
|
||
|
|
1 -> (testUser1, testUser2,True)
|
||
|
|
2 -> (testUser2, testUser1,False)
|
||
|
|
_ -> error "Need either 1 or 2"
|
||
|
|
sessionConnect "localhost"
|
||
|
|
"species64739.dyndns.org"
|
||
|
|
(fromJust $ node we) (resource we) $ do
|
||
|
|
let debug' = liftIO . atomically . debug .
|
||
|
|
(("Thread " ++ show number ++ ":") ++)
|
||
|
|
singleThreaded $ xmppSASL "pwd"
|
||
|
|
xmppThreadedBind (resource we)
|
||
|
|
singleThreaded $ xmppSession
|
||
|
|
sendS . SPresence $ Presence Nothing Nothing Nothing Nothing (Just Available) Nothing Nothing []
|
||
|
|
forkXMPP autoAccept
|
||
|
|
forkXMPP iqResponder
|
||
|
|
-- sendS . SPresence $ Presence Nothing (Just them) Nothing (Just Subscribe) Nothing Nothing Nothing []
|
||
|
|
let delay = if active then 1000000 else 5000000
|
||
|
|
when active . void . forkXMPP . void . forM [1..10] $ \count -> do
|
||
|
|
let message = Text.pack . show $ node we
|
||
|
|
let payload = Payload count (even count) (Text.pack $ show count)
|
||
|
|
let body = pickleElem payloadP payload
|
||
|
|
answer <- sendIQ' (Just them) Get body
|
||
|
|
let answerPayload = unpickleElem payloadP (iqBody answer)
|
||
|
|
expect debug' (invertPayload payload) answerPayload
|
||
|
|
liftIO $ threadDelay delay
|
||
|
|
sendUser "All tests done"
|
||
|
|
liftIO . forever $ threadDelay 10000000
|
||
|
|
return ()
|
||
|
|
return ()
|
||
|
|
|
||
|
|
|
||
|
|
main = do
|
||
|
|
out <- newTChanIO
|
||
|
|
forkIO . forever $ atomically (readTChan out) >>= putStrLn
|
||
|
|
let debugOut = writeTChan out
|
||
|
|
forkIO $ runMain debugOut 1
|
||
|
|
runMain debugOut 2
|
||
|
|
|