ghcjs-websockets-0.2.0.0: GHCJS interface for the Javascript Websocket API

Copyright(c) Justin Le 2015
LicenseMIT
Maintainerjustin@jle.im
Stabilityunstable
Portabilityghcjs
Safe HaskellNone
LanguageHaskell2010

JavaScript.WebSockets.Internal

Contents

Description

Low-level API for the Connection socket wrapper, for situations like debugging when things exported by JavaScript.WebSockets is not enough. Most everyday usage should be covered by the aforementioned module, so don't import this unless you really really have to.

Synopsis

Types

Data types

data Connection

Encapsulates a (reference to a) Javascript Websocket connection. Can be created/accessed with either openConnection or (preferably) withUrl.

Care must be taken to close the connection once you are done if using openConnection, or unprocessed messages and callbacks will continue to queue up.

Constructors

Connection 

Fields

_connSocket :: Socket

JSRef to JS Websocket object

_connQueue :: ConnectionQueue

JSRef to JSArray of queued incoming messages, managed directly in FFI

_connWaiters :: ConnectionWaiters

JSRef to JSArray of queue of waiting receivers, managed directly in FFI

_connOrigin :: Text

Text of server socket was originally opened with

_connClosed :: IORef (Maybe ConnClosing)

IORef with Nothing if the connection is still open and Just reason if it's closed, with the reason

_connBlock :: MVar ()

Mutex for thread-safe manipulation

data SocketMsg

Sum type over the data that can be sent or received through a JavaScript websocket.

What an incoming message is classified as depends on the Javascript Websockets API http://www.w3.org/TR/websockets/, which provides a "typed" input channel of either text or binary blob.

There are several convenience functions to help you never have to deal with this explicitly; its main purpose is if you want to explicitly branch on a receiveMessage depending on what kind of message you receive and do separate things. receiveText and receiveData will both allow you to "filter" incoming messages by their type.

data ConnClosing

Data type containing information on Connection closes.

  • ManualClose: Closed by the Haskell WebSockets interface, using closeConnection or variants.
  • JSClose: Closed on the Javascript end, either by a connection error or server request, or what have you. Contains information from the Javascript Websockets API http://www.w3.org/TR/websockets/#event-definitions.

    The first field is whether or not it was a clean close; the second field is the closing reason code; the third field is a Text with the reason given by the Websockets API.

  • OpenInterupptedClose: There was an unexpected error encountered when attempting to open the connection.
  • UnexpectedClose: Otherwise uncategorized closed status, with a Text field offering a reason.

Typeclasses

class WSSendable s where

A typeclass offering a gratuitous abstraction over what can be sent through a Connection. Allows you to wrap things in a SocketMsg automatically. The only instances that should really ever exist are Text and instances of Binary.

Methods

wrapSendable :: s -> SocketMsg

Instances

class WSReceivable s where

A typeclass offering a gratuitous abstraction over what can be received through a Connection. Allows you to unwrap things in a SocketMsg automatically. The only instances that should really ever exist are Text and instances of Binary.

Exceptions

data ConnectionException

An exception that may be thrown when using the various Connection operations. Right now, only includes ConnectionClosed, which is thrown when using an "unsafe" receive on a closed Connection, or if a Connection closes while an unsafe receive is waiting.

Constructors

ConnectionClosed 

Fields

_socketOrigin :: Text
 

Manipulating and inspecting Connections

openConnectionImmediate :: Text -> IO (MVar Connection)

A version of openConnection that doesn't wait for the connection to be opened. Returns an MVar where the connection can be expected to be placed when it is opened.

closeConnection :: Connection -> IO ()

Manually closes the given Connection. Will un-block all threads currently waiting on the Connection for messages (releasing their callbacks) and disable sending and receiving in the future.

All leftover messages that were never processed on the Haskell end will be deleted; use dumpConnectionQueue to manually fetch them before closing, or closeConnectionLeftovers to recover them while closing.

closeConnectionLeftovers :: Connection -> IO [SocketMsg]

Manually closes the given Connection. It un-blocks all threads currently waiting on the connection and disables all sending and receiving in the future.

The result is a list of all messages received by the connection but not yet retrieved by receive, etc. on the Haskell end.

To close and ignore leftovers, use closeConnection.

clearConnectionQueue :: Connection -> IO ()

Clears the message queue (messages waiting to be received) on the given Connection. Is essentially a no-op on closed connections.

dumpConnectionQueue :: Connection -> IO [SocketMsg]

Returns all incoming messages received by the socket and queued for retrieval using receive functions. Empties the queue.

connectionClosed :: Connection -> IO Bool

Check if the given Connection is closed. Returns a Bool. To check *why* it was closed, see connectionCloseReason.

connectionCloseReason :: Connection -> IO (Maybe ConnClosing)

Returns Nothing if the given Connection is still open, or Just closing containing a ConnClosing with information on why the connection was closed.

For just a Bool saying whether or not the connection is closed, try connectionClosed.

connectionStateCode :: Connection -> IO Int

Returns the "readyState" of the connection's javascript websockets API: 0 is connecting, 1 is open, 2 is closing, and 3 is closed. Shouldn't really be used except for debugging purposes. Use connectionCloseReason whenever possible to get information in a nice haskelley sum type.

Sending and receiving

sendMessage :: Connection -> SocketMsg -> IO Bool

Sends the given SocketMsg through the given Connection. A SocketMsg is a sum type of either 'SocketMsgText t', containing (strict) Text, or 'SocketMsgData d', containing a (lazy) ByteString.

Returns True if the connection is open, and False if it is closed. In the future will return more feedback about whether or not the send was completed succesfully.

receiveMessageMaybe :: Connection -> IO (Maybe SocketMsg)

Block and wait until the Connection receives any message, and returns the message wrapped in a SocketMsg. A SocketMsg is a sum type of either 'SocketMsgText t', containing (strict) Text, or 'SocketMsgData d', containing a (lazy) ByteString.

Will return 'Just msg' as soon as any message is received, or Nothing if the Connection closes first. Returns Nothing immediately if the Connection is already closed.

Connection mutex

withConnBlock :: Connection -> IO a -> IO a

Execute process with the connection mutex lock in effect. Will wait until the lock is released before starting, if lock was already in place.

Will break almost every Connection function if you run one while this is in effect, because almost all of them require the lock to begin.

withConnBlockMasked :: Connection -> IO a -> IO a

Execute process with the connection mutex lock in effect, with asynchronos exceptions masked (See Control.Exception). Will wait until the lock is released before starting, if lock was already in place.

Will break almost every Connection function if you run one while this is in effect, because almost all of them require the lock to begin.