How do you use this library? Here's how:
- Get an enumerator/iteratee pair from your favorite web server, or use
runServer
to set up a simple standalone server. - Read the
Request
usingreceiveRequest
. Inspect its path and the perform the initialhandshake
. This yields aResponse
which you can send back usingsendResponse
. The WebSocket is now ready.
There are (informally) three ways in which you can use the library:
- The most simple case: You don't care about the internal representation of
the messages. In this case, use the
WebSocketsData
typeclass:receiveData
,sendTextData
andsendBinaryData
will be useful. - You have some protocol, and it is well-specified in which cases the client
should send text messages, and in which cases the client should send binary
messages. In this case, you can use the
receiveDataMessage
andsendDataMessage
methods. - You need to write a more low-level server in which you have control over
control frames (e.g. ping/pong). In this case, you can use the
receiveMessage
andsendMessage
methods.
In some cases, you want to escape from the WebSockets
monad and send data
to the websocket from different threads. To this end, the getSender
method is provided.
For a full example, see:
- data WebSocketsOptions = WebSocketsOptions {}
- defaultWebSocketsOptions :: WebSocketsOptions
- data WebSockets a
- runWebSockets :: WebSockets a -> Iteratee ByteString IO () -> Iteratee ByteString IO a
- runWebSocketsWith :: WebSocketsOptions -> WebSockets a -> Iteratee ByteString IO () -> Iteratee ByteString IO a
- runServer :: String -> Int -> WebSockets () -> IO ()
- runWithSocket :: Socket -> WebSockets a -> IO a
- type Headers = [(CI ByteString, ByteString)]
- data Request = Request {}
- data Response = Response {}
- data FrameType
- = ContinuationFrame
- | TextFrame
- | BinaryFrame
- | CloseFrame
- | PingFrame
- | PongFrame
- data Frame = Frame {
- frameFin :: !Bool
- frameType :: !FrameType
- framePayload :: !ByteString
- data Message
- data ControlMessage
- = Close ByteString
- | Ping ByteString
- | Pong ByteString
- data DataMessage
- class WebSocketsData a where
- fromLazyByteString :: ByteString -> a
- toLazyByteString :: a -> ByteString
- data HandshakeError = HandshakeError String
- receiveRequest :: WebSockets (Maybe Request)
- sendResponse :: Response -> WebSockets ()
- handshake :: Request -> Either HandshakeError Response
- receiveFrame :: WebSockets (Maybe Frame)
- sendFrame :: Frame -> WebSockets ()
- receiveMessage :: WebSockets (Maybe Message)
- sendMessage :: Message -> WebSockets ()
- receiveDataMessage :: WebSockets (Maybe DataMessage)
- sendDataMessage :: DataMessage -> WebSockets ()
- receiveData :: WebSocketsData a => WebSockets (Maybe a)
- sendTextData :: WebSocketsData a => a -> WebSockets ()
- sendBinaryData :: WebSocketsData a => a -> WebSockets ()
- type Encoder a = Mask -> a -> Builder
- type Sender a = Encoder a -> a -> IO ()
- send :: Encoder a -> a -> WebSockets ()
- getSender :: WebSockets (Sender a)
- response :: Encoder Response
- frame :: Encoder Frame
- message :: Encoder Message
- controlMessage :: Encoder ControlMessage
- dataMessage :: Encoder DataMessage
- textData :: WebSocketsData a => Encoder a
- binaryData :: WebSocketsData a => Encoder a
WebSocket type
defaultWebSocketsOptions :: WebSocketsOptionsSource
Default options
data WebSockets a Source
The monad in which you can write WebSocket-capable applications
runWebSockets :: WebSockets a -> Iteratee ByteString IO () -> Iteratee ByteString IO aSource
Run a WebSockets
application on an 'Enumerator'/'Iteratee' pair.
runWebSocketsWith :: WebSocketsOptions -> WebSockets a -> Iteratee ByteString IO () -> Iteratee ByteString IO aSource
Version of runWebSockets
which allows you to specify custom options
A simple standalone server
:: String | Address to bind to |
-> Int | Port to listen on |
-> WebSockets () | Application to serve |
-> IO () | Never returns |
Provides a simple server. This function blocks forever. Note that this is merely provided for quick-and-dirty standalone applications, for real applications, you should use a real server.
runWithSocket :: Socket -> WebSockets a -> IO aSource
This function wraps runWebSockets
in order to provide a simple API for
stand-alone servers.
Types
type Headers = [(CI ByteString, ByteString)]Source
Request headers
Simple request type
Response to a Request
Type of a frame
A frame
Frame | |
|
The kind of message a server application typically deals with
data ControlMessage Source
Different control messages
data DataMessage Source
For an end-user of this library, dealing with Frame
s would be a bit
low-level. This is why define another type on top of it, which represents
data for the application layer.
class WebSocketsData a whereSource
In order to have an even more high-level API, we define a typeclass for values the user can receive from and send to the socket. A few warnings apply:
- Natively, everything is represented as a
ByteString
, so this is the fastest instance - You should only use the
Text
or theText
instance when you are sure that the data is UTF-8 encoded (which is the case forText
messages). - Messages can be very large. If this is the case, it might be inefficient to
use the strict
ByteString
andText
instances.
fromLazyByteString :: ByteString -> aSource
toLazyByteString :: a -> ByteStringSource
Initial handshake
data HandshakeError Source
Error in case of failed handshake.
sendResponse :: Response -> WebSockets ()Source
Send a Response
to the socket immediately.
handshake :: Request -> Either HandshakeError ResponseSource
Provides the logic for the initial handshake defined in the WebSocket
protocol. This function will provide you with a Response
which accepts and
upgrades the received Request
. Once this Response
is sent, you can start
sending and receiving actual application data.
In the case of a malformed request, a HandshakeError
is returned.
Sending and receiving
sendFrame :: Frame -> WebSockets ()Source
A low-level function to send an arbitrary frame over the wire.
receiveMessage :: WebSockets (Maybe Message)Source
Receive a message
sendMessage :: Message -> WebSockets ()Source
Send a message
receiveDataMessage :: WebSockets (Maybe DataMessage)Source
Receive an application message. Automatically respond to control messages.
sendDataMessage :: DataMessage -> WebSockets ()Source
Send an application-level message.
receiveData :: WebSocketsData a => WebSockets (Maybe a)Source
Receive a message, treating it as data transparently
sendTextData :: WebSocketsData a => a -> WebSockets ()Source
Send a text message
sendBinaryData :: WebSocketsData a => a -> WebSockets ()Source
Send some binary data
Advanced sending
getSender :: WebSockets (Sender a)Source
In case the user of the library wants to do asynchronous sending to the
socket, he can extract a Sender
and pass this value around, for example,
to other threads.
controlMessage :: Encoder ControlMessageSource
Encode a control message
dataMessage :: Encoder DataMessageSource
Encode an application message
textData :: WebSocketsData a => Encoder aSource
binaryData :: WebSocketsData a => Encoder aSource