WebSocket

WebSocket client, based on the browser api, though also with other api options.

import arsd.http2;

void main() {
	auto ws = new WebSocket(Uri("ws://...."));

	ws.onmessage = (in char[] msg) {
		ws.send("a reply");
	};

	ws.connect();

	WebSocket.eventLoop();
}

Constructors

this
this(Uri uri, Config config)

wss://echo.websocket.org

Members

Foundational

Used with all API styles.

Foundational Functions

close
void close(int code, string reason)

Closes the connection, sending a graceful teardown message to the other side.

ping
void ping(ubyte[] data)

Sends a ping message to the server. This is done automatically by the library if you set a non-zero Config.pingFrequency, but you can also send extra pings explicitly as well with this function.

pong
void pong(ubyte[] data)

Sends a pong message to the server. This is normally done automatically in response to pings.

send
void send(char[] textData)

Sends a text message through the websocket.

send
void send(ubyte[] binaryData)

Sends a binary message through the websocket.

Browser api

API based on the standard in the browser.

Event loop integration

Integrating with external event loops is done through static functions. You should call these BEFORE doing anything else with the WebSocket module or class.

NOT IMPLEMENTED
WebSocket.setEventLoopProxy(arsd.simpledisplay.EventLoop.proxy.tupleof);
// or something like that. it is not implemented yet.
NOT IMPLEMENTED

Blocking api

The blocking API is best used when you only need basic functionality with a single connection.

WebSocketFrame msg;
do {
	// FIXME good demo
} while(msg);

Or to check for blocks before calling:

try_to_process_more:
while(ws.isMessageBuffered()) {
	auto msg = ws.waitForNextMessage();
	// process msg
}
if(ws.isDataPending()) {
	ws.lowLevelReceive();
	goto try_to_process_more;
} else {
	// nothing ready, you can do other things
	// or at least sleep a while before trying
	// to process more.
	if(ws.readyState == WebSocket.OPEN) {
		Thread.sleep(1.seconds);
		goto try_to_process_more;
	}
}

Blocking api Functions

isDataPending
bool isDataPending(Duration timeout)

Is data pending on the socket? Also check isMessageBuffered to see if there is already a message in memory too.

isMessageBuffered
bool isMessageBuffered()

Is there a message in the buffer already? If true, waitForNextMessage is guaranteed to return immediately. If false, check isDataPending as the next step.

lowLevelReceive
bool lowLevelReceive()

Waits for more data off the low-level socket and adds it to the pending buffer.

waitForNextMessage
WebSocketFrame waitForNextMessage()

Waits for and returns the next complete message on the socket.

waitForNextMessageWouldBlock
bool waitForNextMessageWouldBlock()

Tells if waitForNextMessage would block.

Other

Other Functions

connect
void connect()

Group: foundational

onmessage
void onmessage(void delegate(in ubyte[]) dg)

Group: browser_api

onmessage
void onmessage(void delegate(in char[]) dg)

Group: browser_api

readyState
int readyState()

Returns one of CONNECTING, OPEN, CLOSING, or CLOSED.

Other Manifest constants

CLOSED
enum CLOSED;

The connection is closed or couldn't be opened.

CLOSING
enum CLOSING;

The connection is in the process of closing.

CONNECTING
enum CONNECTING;

Socket has been created. The connection is not yet open.

OPEN
enum OPEN;

The connection is open and ready to communicate.

Other Static functions

eventLoop
void eventLoop(shared(bool)* localLoopExited)

Runs an event loop with all known websockets on this thread until all websockets are closed or unregistered, or until you call exitEventLoop, or set *localLoopExited to false (please note it may take a few seconds until it checks that flag again; it may not exit immediately).

exitEventLoop
void exitEventLoop()

Exits all running WebSocket.eventLoops next time they loop around. You can call this from a signal handler or another thread.

Other Structs

CloseEvent
struct CloseEvent

Arguments for the close event. The code and reason are provided from the close message on the websocket, if they are present. The spec says code 1000 indicates a normal, default reason close, but reserves the code range from 3000-5000 for future definition; the 3000s can be registered with IANA and the 4000's are application private use. The reason should be user readable, but not displayed to the end user. wasClean is true if the server actually sent a close event, false if it just disconnected.

Config
struct Config

Group: foundational

Other Variables

onbinarymessage
void delegate(in ubyte[]) onbinarymessage;
onclose
arsd.core.FlexibleDelegate!(void delegate(CloseEvent event)) onclose;

The CloseEvent you get references a temporary buffer that may be overwritten after your handler returns. If you want to keep it or the event.reason member, remember to .idup it.

onerror
void delegate() onerror;
onopen
void delegate() onopen;
ontextmessage
void delegate(in char[]) ontextmessage;
Suggestion Box / Bug Report