Skip to content

zachshattuck/gows

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

gows

Barebones WebSocket (RFC6455) library in Go

What it offers:

  • Simple way to upgrade an HTTP connection to a WebSocket connection
  • Functions to serialize and deserialize individual WebSocket frames

What it doesn't do:

  • Doesn't handle message fragmentation, but you can do that yourself by reading Fin and Opcode. For more information, see section 5.4 of RFC6455
  • Doesn't automatically respond to PING frames
  • Doesn't really offer an opinion on how to handle opcodes or other flags at all

Installation

go get github.com/zachshattuck/gows

Example Usage

import (
	"github.com/zachshattuck/gows"
)

func main() {

	ln, err := net.Listen("tcp", "127.0.0.1:8080")
	if err != nil {
		fmt.Println("Failed to `net.Listen`: ", err)
		os.Exit(1)
	}

	conn, err := ln.Accept()
	if err != nil {
		fmt.Println("Failed to `Accept` connection: ", err)
		os.Exit(1)
	}

	buf := make([]byte, 4096)

	// Will `Read` from the connection and send a `101 Switching Protocols` response
	// if valid, otherwise sends a `400 Bad Request` response.
	err := gows.UpgradeConnection(&conn, buf)
	if err != nil {
		fmt.Fprintln(os.Stderr, "Failed to upgrade: ", err)
		os.Exit(1)
	}

	// Listen for WebSocket frames
	for {
		n, err := conn.Read(buf)
		if err != nil {
			fmt.Println("Failed to read: ", err)
			break
		}

		frame, err := gows.DeserializeWebSocketFrame(buf[:n])
		if err != nil {
			fmt.Fprintln(os.Stderr, "Failed to deserialize frame: ", err)
			continue
		}

		switch frame.Opcode {
		case gows.WS_OP_TEXT: // Handle text frame..
		case gows.WS_OP_BIN: // Handle binary frame..
		case gows.WS_OP_PING:
			fmt.Println("Ping frame, responding with pong...")
			pongFrame := gows.SerializeWebSocketFrame(gows.WebSocketFrame{
				Fin:  1,
				Rsv1: 0, Rsv2: 0, Rsv3: 0,
				Opcode:   gows.WS_OP_PONG,
				IsMasked: 0,
				MaskKey:  [4]byte{},
				Payload:  frame.Payload,
			})
			conn.Write(pongFrame)
		}

	}

}