websockets-0.10.0.0: A sensible and clean way to write WebSocket-capable servers in Haskell.

Safe HaskellNone
LanguageHaskell98

Network.WebSockets

Contents

Synopsis

Incoming connections and handshaking

data PendingConnection Source #

A new client connected to the server. We haven't accepted the connection yet, though.

pendingRequest :: PendingConnection -> RequestHead Source #

Useful for e.g. inspecting the request path.

acceptRequest :: PendingConnection -> IO Connection Source #

Accept a pending connection, turning it into a Connection.

data AcceptRequest Source #

This datatype allows you to set options for acceptRequestWith. It is strongly recommended to use defaultAcceptRequest and then modify the various fields, that way new fields introduced in the library do not break your code.

Constructors

AcceptRequest 

Fields

acceptRequestWith :: PendingConnection -> AcceptRequest -> IO Connection Source #

This function is like acceptRequest but allows you to set custom options using the AcceptRequest datatype.

Main connection type

Options for connections

data ConnectionOptions Source #

Set options for a Connection.

Constructors

ConnectionOptions 

Fields

  • connectionOnPong :: !(IO ())

    Whenever a pong is received, this IO action is executed. It can be used to tickle connections or fire missiles.

Sending and receiving messages

receiveDataMessage :: Connection -> IO DataMessage Source #

Receive an application message. Automatically respond to control messages.

When the peer sends a close control message, an exception of type CloseRequest is thrown. The peer can send a close control message either to initiate a close or in response to a close message we have sent to the peer. In either case the CloseRequest exception will be thrown. The RFC specifies that the server is responsible for closing the TCP connection, which should happen after receiving the CloseRequest exception from this function.

This will throw ConnectionClosed if the TCP connection dies unexpectedly.

receiveData :: WebSocketsData a => Connection -> IO a Source #

Receive a message, converting it to whatever format is needed.

sendTextData :: WebSocketsData a => Connection -> a -> IO () Source #

Send a message as text

sendTextDatas :: WebSocketsData a => Connection -> [a] -> IO () Source #

Send a collection of messages as text

sendBinaryData :: WebSocketsData a => Connection -> a -> IO () Source #

Send a message as binary data

sendClose :: WebSocketsData a => Connection -> a -> IO () Source #

Send a friendly close message. Note that after sending this message, you should still continue calling receiveDataMessage to process any in-flight messages. The peer will eventually respond with a close control message of its own which will cause receiveDataMessage to throw the CloseRequest exception. This exception is when you can finally consider the connection closed.

sendPing :: WebSocketsData a => Connection -> a -> IO () Source #

Send a ping

HTTP Types

type Headers = [(CI ByteString, ByteString)] Source #

Request headers

data Request Source #

A request with a body

Instances

data RequestHead Source #

An HTTP request. The request body is not yet read.

getRequestSubprotocols :: RequestHead -> [ByteString] Source #

List of subprotocols specified by the client, in order of preference. If the client did not specify a list of subprotocols, this will be the empty list.

data Response Source #

A response including a body

data ResponseHead Source #

HTTP response, without body.

WebSocket message types

data Message Source #

The kind of message a server application typically deals with

data DataMessage Source #

For an end-user of this library, dealing with Frames 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 where Source #

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 the Text instance when you are sure that the data is UTF-8 encoded (which is the case for Text messages).
  • Messages can be very large. If this is the case, it might be inefficient to use the strict ByteString and Text instances.

Minimal complete definition

fromLazyByteString, toLazyByteString

Exceptions

data HandshakeException Source #

Error in case of failed handshake. Will be thrown as an Exception.

TODO: This should probably be in the Handshake module, and is solely here to prevent a cyclic dependency.

Constructors

NotSupported

We don't have a match for the protocol requested by the client. todo: version parameter

MalformedRequest RequestHead String

The request was somehow invalid (missing headers or wrong security token)

MalformedResponse ResponseHead String

The servers response was somehow invalid (missing headers or wrong security token)

RequestRejected Request String

The request was well-formed, but the library user rejected it. (e.g. "unknown path")

OtherHandshakeException String

for example "EOF came too early" (which is actually a parse error) or for your own errors. (like "unknown path"?)

data ConnectionException Source #

Various exceptions that can occur while receiving or transmitting messages

Constructors

CloseRequest Word16 ByteString

The peer has requested that the connection be closed, and included a close code and a reason for closing. When receiving this exception, no more messages can be sent. Also, the server is responsible for closing the TCP connection once this exception is received.

See http://tools.ietf.org/html/rfc6455#section-7.4 for a list of close codes.

ConnectionClosed

The peer unexpectedly closed the connection while we were trying to receive some data. This is a violation of the websocket RFC since the TCP connection should only be closed after sending and receiving close control messages.

ParseException String

The client sent garbage, i.e. we could not parse the WebSockets stream.

Running a standalone server

type ServerApp = PendingConnection -> IO () Source #

WebSockets application that can be ran by a server. Once this IO action finishes, the underlying socket is closed automatically.

runServer Source #

Arguments

:: String

Address to bind

-> Int

Port to listen on

-> ServerApp

Application

-> 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.

Glue for using this package with real servers is provided by:

runServerWith :: String -> Int -> ConnectionOptions -> ServerApp -> IO () Source #

A version of runServer which allows you to customize some options.

Utilities for writing your own server

makeListenSocket :: String -> Int -> IO Socket Source #

Create a standardized socket on which you can listen for incomming connections. Should only be used for a quick and dirty solution! Should be preceded by the call withSocketsDo.

makePendingConnection :: Socket -> ConnectionOptions -> IO PendingConnection Source #

Turns a socket, connected to some client, into a PendingConnection. The PendingConnection should be closed using close later.

Running a client

type ClientApp a = Connection -> IO a Source #

A client application interacting with a single server. Once this IO action finished, the underlying socket is closed automatically.

runClient Source #

Arguments

:: String

Host

-> Int

Port

-> String

Path

-> ClientApp a

Client application

-> IO a 

runClientWith Source #

Arguments

:: String

Host

-> Int

Port

-> String

Path

-> ConnectionOptions

Options

-> Headers

Custom headers to send

-> ClientApp a

Client application

-> IO a 

runClientWithSocket Source #

Arguments

:: Socket

Socket

-> String

Host

-> String

Path

-> ConnectionOptions

Options

-> Headers

Custom headers to send

-> ClientApp a

Client application

-> IO a 

runClientWithStream Source #

Arguments

:: Stream

Stream

-> String

Host

-> String

Path

-> ConnectionOptions

Connection options

-> Headers

Custom headers to send

-> ClientApp a

Client application

-> IO a 

Utilities

forkPingThread :: Connection -> Int -> IO () Source #

Forks a ping thread, sending a ping message every n seconds over the connection. The thread dies silently if the connection crashes or is closed.