packages feed

ghcjs-websockets 0.3.0.1 → 0.3.0.2

raw patch · 6 files changed

+173/−9 lines, 6 filesdep ~text

Dependency ranges changed: text

Files

+ CHANGELOG.md view
@@ -0,0 +1,24 @@+0.3.0.2+-------+<https://github.com/mstksg/ghcjs-websockets/releases/tag/v0.3.0.2>++*   Lowered bounds on *text* dependency.+*   Added `CHANGELOG.md` and `README.md` to extra source dependecy fields, to+    count them in the cabal package.++0.3.0.1+-------+<https://github.com/mstksg/ghcjs-websockets/releases/tag/v0.3.0.1>++*   Fixed the "other-modules" cabal file field to include non-exported but+    important modules.++0.3.0.0+-------+<https://github.com/mstksg/ghcjs-websockets/releases/tag/v0.3.0.0>++*   First official release.  API more or less stabilized.  Library is more or+    less stable, but there are still some extra aspects of the javascript+    websockets API to hook onto for more power/information, and some+    javascript errors to be handled on edge cases.+
+ README.md view
@@ -0,0 +1,144 @@+ghcjs-websockets+================++*ghcjs-websockets* aims to provide a clean, idiomatic, efficient, low-level,+out-of-your-way, bare bones, concurrency-aware interface with minimal+abstractions over the [Javascript Websockets API][jsapi], inspired by common+Haskell idioms found in libraries like [io-stream][] and the server-side+[websockets][] library, targeting compilation to Javascript with `ghcjs`.++The interface abstracts websockets as simple IO/file handles, with additional+access to the natively "typed" (text vs binary) nature of the Javascript+Websockets API.  There are also convenience functions to directly decode+serialized data (serialized with [binary][]) sent through channels.++The library is mostly intended to be a low-level FFI library, with the hopes+that other, more advanced libraries maybe build on the low-level FFI bindings+in order to provide more advanced and powerful abstractions.  Most design+decisions were made with the intent of keeping things as simple as possible in+order for future libraries to abstract over it.++Most of the necessary functionality is in hopefully in+`JavaScript.WebSockets`; more of the low-level API is exposed in+`JavaScript.WebSockets.Internal` if you need it for library construction.++Documenation is [online on github pages][documentation].++[jsapi]: http://www.w3.org/TR/websockets/+[io-stream]: http://hackage.haskell.org/package/io-streams+[websockets]: http://hackage.haskell.org/package/websockets+[binary]: http://hackage.haskell.org/package/binary+[documentation]: http://mstksg.github.io/ghcjs-websockets/JavaScript-WebSockets.html++Usage+-----++```haskell+import Data.Text (unpack)++-- A simple echo client, echoing all incoming text data+main :: IO ()+main = withUrl "ws://my-server.com" $ \conn ->+    forever $ do+        t <- receiveText conn+        putStrLn (unpack t)+        sendText conn t+```++The above code will attempt to interpret all incoming data as UTF8-encoded+Text, and throw away data that does not.++`conn` is a `Connection`, which encapsulates a websocket channel.++You can also do the same thing to interpret all incoming data as any instance+of `Binary` --- say, `Int`s:++```haskell+-- A simple client waiting for connections and outputting the running sum+main :: IO ()+main = withUrl "ws://my-server.com" (runningSum 0)++runningSum :: Int -> Connection -> IO ()+runningSum n conn = do+    i <- receiveData conn+    print (n + i)+    runningSum (n + i) conn+```++`receiveData` will block until the `Connection` receives data that is+decodable as whatever type you expect, and will throw away all nondecodable+data (including `Text` data).++The `receive` function is provided as an over-indulgent layer of abstraction+where you can receive both `Text` and instances of `Binary` with the same+function using typeclass magic --- for the examples above, you could use+`receive` in place of both `receiveText` and `receiveData`.++`send` works the same way for `sendText` and `sendData`.++If you want to, you can access the incoming data directly using the+`SocketMsg` sum type, which exposes either a `Text` or a lazy `ByteString`:++```haskell+import Data.Text (unpack, append)+import qualified Data.ByteString.Base64.Lazy as B64++main :: IO ()+main = withUrl "ws://my-server.com" $ \conn ->+    forever $ do+        msg <- receiveMessage+        putStrLn $ case msg of+            SocketMsgText t ->+                unpack $ append "Received text: " t+            SocketMsgData d ->+                "Received data: " ++ show (B64.encode d)+```++You can talk to multiple connections by nesting `withUrl`:++```haskell+-- Act as a relay between two servers+main :: IO ()+main =  withUrl "ws://server-1.com" $ \conn1 ->+        withUrl "ws://server-2.com" $ \conn2 ->+            forever $ do+                msg <- receiveMessage conn1+                sendMessage conn2 msg+```++And also alternatively, you can manually open and close connections:++```haskell+-- Act as a relay between two servers+main :: IO ()+main = do+    conn1 <- openConnection "ws://server-1.com"+    conn2 <- openConnection "ws://server-2.com"+    forever $ do+        msg <- receiveMessage conn1+        sendMessage conn2 msg+    closeConnection conn2+    closeConnection conn1+```++`receiveMessage` and its varieties will all throw an exception if the+connection closes while they're waiting or if you attempt to receive on a+closed connection.  You can handle these with mechanisms from+`Control.Exception`, or you can use their "maybe"-family counterparts,+`receiveMessageMaybe`, etc., who will return results in `Just` on a success,+or return a `Nothing` if the connection is closed or if receiving on a closed+connection.++You can use also `connectionClosed :: Connection -> IO Bool` to check if the+given `Connection` object is closed (or `connectionCloseReason` to see *why*).++When closing connections, there might be some messages that were received by+the socket but never processed on the Haskell side with a `receive` method.+These will normally be deleted; however, you can use+`closeConnectionLeftovers` or `withUrlLeftovers` to grab a list of the raw+`SocketMsg`s remaining after closing.++### Copyright++Copyright (c) Justin Le 2015+
ghcjs-websockets.cabal view
@@ -1,5 +1,5 @@ name:                ghcjs-websockets-version:             0.3.0.1+version:             0.3.0.2 synopsis:            GHCJS interface for the Javascript Websocket API description:                      Documentation online at@@ -82,7 +82,8 @@ copyright:           Copyright (c) Justin Le 2015 category:            Web build-type:          Simple--- extra-source-files:  +extra-source-files:  CHANGELOG.md+                   , README.md cabal-version:       >=1.10  source-repository head@@ -95,13 +96,13 @@   -- ghcjs-options: -O2   other-modules:       JavaScript.Blob                      , JavaScript.WebSockets.FFI-  -- other-extensions:    +  -- other-extensions:   ghc-options:         -Wall   build-depends:       base              >= 4.7      && < 5                      , base64-bytestring >= 1                      , binary            >= 0.7                      , bytestring        >= 0.10                      , ghcjs-base        >= 0.1-                     , text              >= 1.2+                     , text              >= 1   hs-source-dirs:      src   default-language:    Haskell2010
src/JavaScript/Blob.hs view
@@ -32,6 +32,3 @@  isBlob :: JSRef a -> IO Bool isBlob ref = ffi_blobCheck ref---
src/JavaScript/WebSockets.hs view
@@ -438,4 +438,3 @@ -- | Returns the origin url of the given 'Connection'. connectionOrigin :: Connection -> Text connectionOrigin = _connOrigin-
src/JavaScript/WebSockets/Internal.hs view
@@ -395,4 +395,3 @@       else do         let blob = unsafeCoerce msg :: JSString         return . Just . SocketMsgText . fromJSString $ blob-