DandelionWebSockets.AbstractMatcherType

Abstract type for objects that match actual arguments against expected arguments. For instance, we sometimes don't care what value is provided a mock function, only what type it is. Also, this can be used to parse an actual argument as JSON and compare the resulting object, rather than relying on a string comparison.

All AbstractMatcher types T must define a function mock_match(::T, v::Any).

DandelionWebSockets.WSClientType

A WebSocket client, used to connect to a server, and send messages.

Note: The keyword arguments in the constructor are primarily for testing.

Base.resetMethod

Reset the backoff to its initial state.

DandelionWebSockets.wsconnectMethod

Connect the client to a WebSocket server at uri, and use handler for the callbacks.

Arguments

  • fix_small_message_latency::Bool = false: Set the TCP_NODELAY flag to improve small message latency.

Fix small message latency

The TCP protocol can buffer small messages (1448 bytes and smaller). The reason is that this reduces the overhead when sending large amounts of small packets. However, it also means that latency can be much higher for small messages. This buffering can be disabled by setting a flag TCPNODELAY. By default, the WebSocket client will now set the TCPNODELAY flag.

If your application will send and receive primarily small messages (1448 bytes or smaller), and it is sensitive to latency, then leave fix_small_message_latency set to true (now the default). This sets the TCPNODELAY flag. If you are not concerned about latency, but concerned about throughput for many small messages, then you can set `fixsmallmessagelatency = false`. Then you may get higher throughput, at the expense of higher latency for small messages.

DandelionWebSockets.@mockfunctionMacro

Define one or more functions that mock the behaviour the object should have.

The functions defined here are the functions called by the code under test. The functions check that their arguments match those that are expected, and that the mock action is performed.

DandelionWebSockets.ClientProtocolInputType

Abstract type for all commands sent to ClientProtocol.

These commands are sent as arguments to the different handle functions on ClientProtocol. Each command represents an action on a WebSocket, such as sending a text frame, ping request, or closing the connection.

DandelionWebSockets.CloseStatusType

CloseStatusCode indicates a reason for closing the connection. It is optionally sent as the first two bytes of a Close frames payload.

DandelionWebSockets.FailTheConnectionBehaviourType

Failing the WebSocket connection is an action taken at certain points in the protocol specification, in response to error conditions.

The closing behaviour is to optionally send a Close frame, with an appropriate status code, and then close the socket.

DandelionWebSockets.FrameSenderType

FrameSender is used to send multi-frame messages.

You are provided a FrameSender via the client. You then send data using the sendframe(sender, data; isfinal=false) method. For the last frame you set isfinal = true.

After the last frame has been sent, you MAY NOT use the FrameSender again. Trying to send another frame with the same instance of FrameSender WILL lead to an exception of type FinalFrameAlreadySentException.

NOTE: While you have a FrameSender in which you have not sent the last frame, then you MAY NOT use the client to send any other messages. Interleaving messages is prohibited by the WebSocket protocol and will lead to the socket being closed.

NOTE: You may send frames that are individually invalid UTF-8. However, the complete message, which is all frames concatenated, MUST be valid UTF-8, or the other endpoint is required to fail the WebSocket connection. With the TextFrameSender you can use both a String or a Vector{UInt8} as the payload. The Vector{UInt8} alternative can be used to send invalid UTF-8, or possibly invalid UTF-8.

Example

sender = sendmultiframetext(client)
sendframe(sender, "Hello")
sendframe(sender, "world")
sendframe(sender, "Goodbye"; isfinal=true)

Example

sender = sendmultiframebinary(client)
sendframe(sender, b"Hello")
sendframe(sender, b"world")
sendframe(sender, b"Goodbye"; isfinal=true)
DandelionWebSockets.FrameWriterType

FrameWriter is used by the protocols to write frames to a socket.

This is separate from the client protocol code, because the protocol for closing a connection is separate from the rest of the client protocol, and both need to send frames.

DandelionWebSockets.HTTPAdapterType

HTTPAdapter is an abstract type for an HTTP package that can be used for a handshake GET.

Any subtype of HTTPAdapter should implement the dohandshake method.

DandelionWebSockets.HTTPHandshakeType

HTTPHandshake implements the HTTP handshake from the WebSocket specification.

It requires a random number generator to generate the WebSocket random key used to verify that the other side is actually a WebSocket server. The HTTPAdapter supplied implements the actual HTTP GET request, which returns an HTTPUpgradeResponse.

DandelionWebSockets.TLSBufferedIOType

TLSBufferedIO adapts a TLS socket so we can do byte I/O.

The stream returned by MbedTLS when using a TLS socket does not support the byte I/O used when reading a frame. It only supports reading a chunk of data. This is a fake stream that buffers some data and lets us do byte I/O.

Note: This should have been done by the BufferedStreams.jl package. However, I couldn't get it to work with the MbedTLS stream, for reasons unknown. If we can investigate and fix that problem, then we should really replace this type with a BufferedInputStream.

DandelionWebSockets.WebSocketHandshakeType

WebSocketHandshake represents a way to make a WebSocket connection handshake.

The only handshake detailed in the specification is an HTTP handshake, represented by the HTTPHandshake type (regardless of HTTP package used to implement it). The specification does mention the possibility of other types of handshakes, even though these would be outside of the specification.

DandelionWebSockets.connection_result_Method
connection_result(::WSClient, ::GoodHandshake, ::WebSocketHandler, fix_small_message_latency::Bool)

For a valid handshake, start all background tasks for this connection. This includes tasks for reading and writing from the socket, as well as a task for user callback.

DandelionWebSockets.dohandshakeMethod
dohandshake(http::HTTPAdapter, uri::String, headers::HeaderList)

Do an HTTP GET request to uri including headers headers.

The headers list will contain all WebSocket upgrade specific headers, such as Connection, Upgrade, and Sec-WebSocket-Key.

DandelionWebSockets.performhandshakeMethod
performhandshake(h::HTTPHandshake, uri::String)

Do a handshake with the server at uri, with parameters supplied by h. Validate the handshake, and return a good or bad result, depending on the validation.

DandelionWebSockets.sendframeMethod

Send a frame with a payload to the other endpoint. isfinal must be set to true for the last frame.

After the call with isfinal = true, then this method MAY NOT be called again. If it is, then a FinalFrameAlreadySentException will be thrown.

DandelionWebSockets.tcpnodelayMethod
tcpnodelay(::IO)

Sets the TCP_NODELAY flag on a socket. This is a separate function only for testing purposes. It can be implemented with a more specific type if the flag makes no sense for another IO subtype.