-
Notifications
You must be signed in to change notification settings - Fork 145
/
Copy pathForeign.hs
44 lines (37 loc) · 1.68 KB
/
Foreign.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
{-# LANGUAGE ForeignFunctionInterface, JavaScriptFFI, CPP #-}
module Reflex.Dom.WebSocket.Foreign where
import Prelude hiding (div, span, mapM, mapM_, concat, concatMap, all, sequence)
import Data.ByteString (ByteString)
import qualified Data.ByteString as BS
import GHCJS.Types
import GHCJS.DOM.WebSocket (message, open, closeEvent)
import qualified GHCJS.DOM.WebSocket as GD
import GHCJS.DOM.MessageEvent
import GHCJS.DOM.EventM (on)
import GHCJS.DOM.Types
import Control.Monad.IO.Class
import Control.Monad.Reader
import GHCJS.Buffer
import JavaScript.TypedArray.ArrayBuffer as JS
import GHCJS.Marshal.Pure
data JSWebSocket = JSWebSocket { unWebSocket :: WebSocket }
newWebSocket :: a -> String -> (ByteString -> IO ()) -> IO () -> IO () -> IO JSWebSocket
newWebSocket _ url onMessage onOpen onClose = do
ws <- GD.newWebSocket url (Just [] :: Maybe [String])
_ <- on ws open $ liftIO onOpen
GD.setBinaryType ws "arraybuffer"
_ <- on ws message $ do
e <- ask
d <- getData e
ab <- liftIO $ unsafeFreeze $ pFromJSVal d
liftIO $ onMessage $ toByteString 0 Nothing $ createFromArrayBuffer ab
_ <- on ws closeEvent $ liftIO onClose
return $ JSWebSocket ws
webSocketSend :: JSWebSocket -> ByteString -> IO ()
webSocketSend (JSWebSocket ws) bs = do
let (b, off, len) = fromByteString bs
ab <- ArrayBuffer <$> if BS.length bs == 0 --TODO: remove this logic when https://github.com/ghcjs/ghcjs-base/issues/49 is fixed
then jsval . getArrayBuffer <$> create 0
else return $ js_dataView off len $ jsval $ getArrayBuffer b
GD.send ws $ Just ab
foreign import javascript safe "new DataView($3,$1,$2)" js_dataView :: Int -> Int -> JSVal -> JSVal