HORIZON HASKELLDocslts/ghc-9.10.xc74966e2026-09-27Search names, modules, packages, or :: a typeCtrl K

GHC 9.10.3 · lts/ghc-9.10.x · c74966e · 2026-09-27

Incoming connections and handshaking

10 declarations
datadata PendingConnection
#

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

datadata AcceptRequest
#

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

Main connection type

1 declaration

Options for connections

2 declarations
datadata ConnectionOptions
#

Set options for a Connection. Please do not use this constructor directly, but rather use defaultConnectionOptions and then set the fields you want, e.g.:

myOptions = defaultConnectionOptions {connectionStrictUnicode = True}

This way your code does not break if the library introduces new fields.

Constructors

  • ConnectionOptions
    • connectionOnPong :: !IO ()

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

    • connectionTimeout :: !Int

      Timeout for connection establishment in seconds. Only used in the client.

    • connectionCompressionOptions :: !CompressionOptions
    • connectionStrictUnicode :: !Bool

      Enable strict unicode on the connection. This means that if a client (or server) sends invalid UTF-8, we will throw a UnicodeException rather than replacing it by the unicode replacement character U+FFFD.

    • connectionFramePayloadSizeLimit :: !SizeLimit

      The maximum size for incoming frame payload size in bytes. If a frame exceeds this limit, a ParseException is thrown.

    • connectionMessageDataSizeLimit :: !SizeLimit

      connectionFrameSizeLimit is often not enough since a malicious client can send many small frames to create a huge message. This limit allows you to protect from that. If a message exceeds this limit, a ParseException is thrown.

      Note that, if compression is enabled, we check the size of the compressed messages, as well as the size of the uncompressed messages as we are deflating them to ensure we don't use too much memory in any case.

The default connection options:

  • Nothing happens when a pong is received.

  • Compression is disabled.

  • Lenient unicode decoding.

  • 30 second timeout for connection establishment.

Compression options

datadata PermessageDeflate
#

Four extension parameters are defined for "permessage-deflate" to help endpoints manage per-connection resource usage.

  • "server_no_context_takeover"

  • "client_no_context_takeover"

  • "server_max_window_bits"

  • "client_max_window_bits"

Instances2Eq, Show

Protection limits

datadata SizeLimit
#

A size limit, in bytes. The Monoid instance takes the minimum limit.

Instances4Eq, Show, Semigroup, Monoid
  • Eq SizeLimitDefined in websockets-0.13.0.0 · Network.WebSockets.Connection.Options
  • Show SizeLimitDefined in websockets-0.13.0.0 · Network.WebSockets.Connection.Options
  • Semigroup SizeLimitDefined in websockets-0.13.0.0 · Network.WebSockets.Connection.Options
  • Monoid SizeLimitDefined in websockets-0.13.0.0 · Network.WebSockets.Connection.Options

Sending and receiving messages

13 declarations

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.

valuesendTextData :: WebSocketsData a => Connection -> a -> IO ()
#

Send a textual message. The message will be encoded as UTF-8. This should be the default choice for human-readable text-based protocols such as JSON.

valuesendClose :: WebSocketsData a => Connection -> a -> IO ()
#

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.

HTTP Types

6 declarations

WebSocket message types

4 declarations
datadata DataMessage
#

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.

There are currently two kinds of data messages supported by the WebSockets protocol:

  • Textual UTF-8 encoded data. This corresponds roughly to sending a String in JavaScript.

  • Binary data. This corresponds roughly to send an ArrayBuffer in JavaScript.

Constructors

  • Text ByteString (Maybe Text)

    A textual message. The second field might contain the decoded UTF-8 text for caching reasons. This field is computed lazily so if it's not accessed, it should have no performance impact.

  • Binary ByteString

    A binary message.

Instances2Eq, Show
  • Eq DataMessageDefined in websockets-0.13.0.0 · Network.WebSockets.Types
  • Show DataMessageDefined in websockets-0.13.0.0 · Network.WebSockets.Types
classclass WebSocketsData a where
#

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.

Instances4WebSocketsData

Exceptions

2 declarations
datadata HandshakeException
#

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

Instances2Show, Exception
datadata ConnectionException
#

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.

  • UnicodeException String

    The client sent invalid UTF-8. Note that this exception will only be thrown if strict decoding is set in the connection options.

Instances3Eq, Show, Exception

Running a standalone server

6 declarations
typetype ServerApp = PendingConnection -> IO ()
#

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

valuerunServer
  1. :: String

    Address to bind

  2. -> Int

    Port to listen on

  3. -> ServerApp

    Application

  4. -> IO ()

    Never returns

#

Provides a simple server. This function blocks forever. Note that this is merely provided for quick-and-dirty or internal applications, but for real applications, you should use a real server.

For example:

  • Performance is reasonable under load, but:

  • No protection against DoS attacks is provided.

  • No logging is performed.

  • ...

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

Utilities for writing your own server

3 declarations
valuemakeListenSocket :: String -> Int -> IO Socket
#

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 Network.Socket.withSocketsDo.

Running a client

6 declarations
typetype ClientApp a = Connection -> IO a
#

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

Utilities

5 declarations
valuewithPingThread
  1. :: Connection
  2. -> Int

    Second interval in which pings should be sent.

  3. -> IO ()

    Repeat this after sending a ping.

  4. -> IO a

    Application to wrap with a ping thread.

  5. -> IO a

    Executes application and kills ping thread when done.

#

Forks a ping thread, sending a ping message every n seconds over the connection. The thread is killed when the inner IO action is finished.

This is useful to keep idle connections open through proxies and whatnot. Many (but not all) proxies have a 60 second default timeout, so based on that sending a ping every 30 seconds is a good idea.

Note that usually you want to use withPingPong to timeout the connection if a pong is not received.

valueforkPingThread :: Connection -> Int -> IO ()
#

Deprecated. Use withPingThread instead

DEPRECATED: Use withPingThread instead.

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.

This is useful to keep idle connections open through proxies and whatnot. Many (but not all) proxies have a 60 second default timeout, so based on that sending a ping every 30 seconds is a good idea.