Slide 57 of 74

WebSockets

proc handle(conn: hive.net.WsConnection): void {
	// The connection lasts as long as the handler does, so it loops
	// until the other side hangs up.
	mut open := true
	for ; open; {
		got := hive.net.wsReceive(conn)
		if got is Result.Ok(msg) {
			hive.net.wsSend(conn, "echo: {msg}")
		} else {
			open = false
		}
	}
}

proc main(): void {
	hive.net.wsServe(8081, handle)
}

WebSockets are RFC 6455 end to end: the handshake, framing, masking, ping and pong and fragmentation are the runtime's business, and a program only ever sees whole messages, as a Str.

  • wsServe(port, handler) calls a proc(WsConnection): void once per connection, each on a thread of its own, and the connection closes when the handler returns — so a handler that means to talk more than once loops.
  • wsConnect(url) dials one as a client, answering with a Result.
  • wsReceive(conn) waits for the next message; wsSend(conn, message) answers with the bytes it sent; wsClose(conn) ends it from this side.
  • wsRequest(conn) is the HttpRequest that opened the connection, as a plain value.

A hive.net.WsError carries a reason — "Handshake", "Protocol", "Closed", "Send" or "Receive" — and a message. A peer hanging up is "Closed", which is how a conversation ends rather than a failure worth reporting.