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.
165 lines
5.6 KiB
165 lines
5.6 KiB
|
14 years ago
|
{-# LANGUAGE PackageImports, OverloadedStrings, NoMonomorphismRestriction #-}
|
||
|
14 years ago
|
module Example where
|
||
|
|
|
||
|
|
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
|
||
|
|
|
||
|
14 years ago
|
import Network.XMPP
|
||
|
14 years ago
|
import Network.XMPP.IM.Presence
|
||
|
14 years ago
|
import Network.XMPP.Pickle
|
||
|
|
|
||
|
|
import System.Environment
|
||
|
14 years ago
|
import Text.XML.Stream.Elements
|
||
|
14 years ago
|
|
||
|
|
testUser1 :: JID
|
||
|
|
testUser1 = read "testuser1@species64739.dyndns.org/bot1"
|
||
|
|
|
||
|
|
testUser2 :: JID
|
||
|
|
testUser2 = read "testuser2@species64739.dyndns.org/bot2"
|
||
|
|
|
||
|
14 years ago
|
supervisor :: JID
|
||
|
|
supervisor = read "uart14@species64739.dyndns.org"
|
||
|
14 years ago
|
|
||
|
|
|
||
|
14 years ago
|
attXmpp :: STM a -> XMPP a
|
||
|
14 years ago
|
attXmpp = liftIO . atomically
|
||
|
|
|
||
|
|
testNS :: Text
|
||
|
|
testNS = "xmpp:library:test"
|
||
|
|
|
||
|
14 years ago
|
data Payload = Payload
|
||
|
|
{ payloadCounter ::Int
|
||
|
|
, payloadFlag :: Bool
|
||
|
|
, payloadText :: Text
|
||
|
|
} deriving (Eq, Show)
|
||
|
14 years ago
|
|
||
|
|
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
|
||
|
14 years ago
|
chan' <- listenIQChan Get testNS
|
||
|
|
chan <- case chan' of
|
||
|
|
Nothing -> liftIO $ putStrLn "Channel was already taken"
|
||
|
|
>> error "hanging up"
|
||
|
|
Just c -> return c
|
||
|
14 years ago
|
forever $ do
|
||
|
14 years ago
|
next <- liftIO . atomically $ readTChan chan
|
||
|
|
let Right payload = unpickleElem payloadP . iqRequestPayload $
|
||
|
|
iqRequestBody next
|
||
|
14 years ago
|
let answerPayload = invertPayload payload
|
||
|
|
let answerBody = pickleElem payloadP answerPayload
|
||
|
14 years ago
|
answerIQ next (Right $ Just answerBody)
|
||
|
14 years ago
|
when (payloadCounter payload == 10) $ do
|
||
|
|
liftIO $ threadDelay 1000000
|
||
|
|
endSession
|
||
|
14 years ago
|
|
||
|
14 years ago
|
autoAccept :: XMPP ()
|
||
|
14 years ago
|
autoAccept = forever $ do
|
||
|
14 years ago
|
st <- waitForPresence isPresenceSubscribe
|
||
|
14 years ago
|
sendPresence $ presenceSubscribed (fromJust $ presenceFrom st)
|
||
|
14 years ago
|
|
||
|
14 years ago
|
simpleMessage :: JID -> Text -> Message
|
||
|
|
simpleMessage to txt = message
|
||
|
|
{ messageTo = Just to
|
||
|
14 years ago
|
, messagePayload = [Element "body"
|
||
|
14 years ago
|
[]
|
||
|
|
[NodeContent $ ContentText txt]
|
||
|
|
]
|
||
|
|
}
|
||
|
|
where
|
||
|
|
message = Message { messageID = Nothing
|
||
|
|
, messageFrom = Nothing
|
||
|
|
, messageTo = Nothing
|
||
|
|
, messageLangTag = Nothing
|
||
|
|
, messageType = Normal
|
||
|
|
, messagePayload = []
|
||
|
|
}
|
||
|
|
|
||
|
14 years ago
|
|
||
|
14 years ago
|
sendUser = sendMessage . simpleMessage supervisor . Text.pack
|
||
|
14 years ago
|
|
||
|
|
expect debug x y | x == y = debug "Ok."
|
||
|
|
| otherwise = do
|
||
|
|
let failMSG = "failed" ++ show x ++ " /= " ++ show y
|
||
|
|
debug failMSG
|
||
|
|
sendUser failMSG
|
||
|
|
|
||
|
|
|
||
|
14 years ago
|
wait3 :: MonadIO m => m ()
|
||
|
|
wait3 = liftIO $ threadDelay 1000000
|
||
|
|
|
||
|
14 years ago
|
runMain :: (String -> STM ()) -> Int -> IO ()
|
||
|
|
runMain debug number = do
|
||
|
14 years ago
|
let (we, them, active) = case number `mod` 2 of
|
||
|
14 years ago
|
1 -> (testUser1, testUser2,True)
|
||
|
14 years ago
|
0 -> (testUser2, testUser1,False)
|
||
|
14 years ago
|
let debug' = liftIO . atomically .
|
||
|
|
debug . (("Thread " ++ show number ++ ":") ++)
|
||
|
14 years ago
|
wait <- newEmptyTMVarIO
|
||
|
14 years ago
|
withNewSession $ do
|
||
|
14 years ago
|
setSessionEndHandler (liftIO . atomically $ putTMVar wait ())
|
||
|
14 years ago
|
setConnectionClosedHandler (\e -> do
|
||
|
|
liftIO (debug' $ "connection lost because " ++ show e)
|
||
|
|
endSession )
|
||
|
14 years ago
|
debug' "running"
|
||
|
14 years ago
|
withConnection $ do
|
||
|
|
connect "localhost" "species64739.dyndns.org"
|
||
|
|
startTLS exampleParams
|
||
|
|
saslResponse <- auth (fromJust $ localpart we) "pwd" (resourcepart we)
|
||
|
|
case saslResponse of
|
||
|
|
Right _ -> return ()
|
||
|
|
Left e -> error $ show e
|
||
|
|
debug' "session standing"
|
||
|
14 years ago
|
sendPresence presenceOnline
|
||
|
14 years ago
|
fork autoAccept
|
||
|
14 years ago
|
sendPresence $ presenceSubscribe them
|
||
|
14 years ago
|
fork iqResponder
|
||
|
14 years ago
|
when active $ do
|
||
|
|
liftIO $ threadDelay 1000000 -- Wait for the other thread to go online
|
||
|
14 years ago
|
void . fork $ do
|
||
|
14 years ago
|
forM [1..10] $ \count -> do
|
||
|
|
let message = Text.pack . show $ localpart we
|
||
|
|
let payload = Payload count (even count) (Text.pack $ show count)
|
||
|
|
let body = pickleElem payloadP payload
|
||
|
|
debug' "sending"
|
||
|
|
Right answer <- sendIQ' (Just them) Get Nothing body
|
||
|
|
debug' "received"
|
||
|
|
let Right answerPayload = unpickleElem payloadP
|
||
|
|
(fromJust $ iqResultPayload answer)
|
||
|
|
expect debug' (invertPayload payload) answerPayload
|
||
|
|
liftIO $ threadDelay 100000
|
||
|
|
sendUser "All tests done"
|
||
|
|
debug' "ending session"
|
||
|
|
liftIO . atomically $ putTMVar wait ()
|
||
|
|
endSession
|
||
|
14 years ago
|
liftIO . atomically $ takeTMVar wait
|
||
|
14 years ago
|
return ()
|
||
|
|
return ()
|
||
|
|
|
||
|
14 years ago
|
run i = do
|
||
|
14 years ago
|
out <- newTChanIO
|
||
|
|
forkIO . forever $ atomically (readTChan out) >>= putStrLn
|
||
|
|
let debugOut = writeTChan out
|
||
|
14 years ago
|
forkIO $ runMain debugOut (1 + i)
|
||
|
|
runMain debugOut (2 + i)
|
||
|
|
|
||
|
|
main = run 0
|
||
|
14 years ago
|
|