websocket

package module
v0.0.0-...-fb931f7 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 4, 2025 License: MIT Imports: 11 Imported by: 0

README

websocket

websocket is an external dependency free, pure go implementation of RFC-6455. This project is currently in its alpha stage and the APIs can break in new releases.

Getting started

Prerequisites

websocket requires Go version 1.23 or above.

Getting websocket

With Go's module support, go [build|run|test] automatically fetches the necessary dependencies when you add the import in your code:

import "github.com/ajsqr/websocket"

Alternatively, use go get:

go get -u github.com/ajsqr/websocket"

Running websocket

A basic example:

package main

import (
	 "github.com/ajsqr/websocket"
	 "github.com/go-chi/chi/v5"
	 "net/http"
	 "time"
	 "fmt"
)

var opener = websocket.WSOpener{
	MaxBytes: 20,
}

func hello(w http.ResponseWriter, r *http.Request) {
	ctx := r.Context()
	ws, err := opener.Open(w,r, websocket.TextWebsocket)
	if err != nil{
		panic(err.Error())
	}

	// wait for a message from the client
	clientHello, err := ws.Receive(ctx)
	if err != nil{
		panic(err.Error())
	}

	fmt.Printf("client says : %s", string(clientHello))

	for {
		err := ws.Send(ctx, []byte("hello"))
		if err != nil{
			panic(err.Error())
		}

		time.Sleep(5*time.Second)
	}

}

func main() {
	router := chi.NewRouter()
	router.Get("/", hello)
	err := http.ListenAndServe(":8123", router)
	if err != nil{
		panic(err.Error())
	}
}

Contributing

Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.

Please make sure to update tests as appropriate.

License

MIT

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	BadRequest = errors.New("bad request")

	InvalidFrameType = errors.New("invalid frame type")

	HijackingNotSupported = errors.New("response writer implementation does not support hijacking")

	InvalidOpcode = errors.New("invalid opcode")

	InvalidLength = errors.New("invalid length")
)

Functions

This section is empty.

Types

type Frame

type Frame struct {
	// Indicates that this is the final fragment in a message.
	// The first fragment MAY also be the final fragment.
	FIN bool

	// MUST be 0 unless an extension is negotiated that defines meanings
	// for non-zero values.  If a nonzero value is received and none of
	// the negotiated extensions defines the meaning of such a nonzero
	// value, the receiving endpoint MUST _Fail the WebSocket
	// Connection_.
	RSV1 bool

	RSV2 bool

	RSV3 bool

	// Opcode Defines the interpretation of the "Payload data".  If an unknown
	// opcode is received, the receiving endpoint MUST _Fail the
	// WebSocket Connection_.
	Opcode Opcode

	// Defines whether the "Payload data" is masked.  If set to 1, a
	// masking key is present in masking-key, and this is used to unmask
	// the "Payload data" as per Section 5.3.  All frames sent from
	// client to server have this bit set to 1
	Mask bool

	// All frames sent from the client to the server are masked by a
	// 32-bit value that is contained within the frame.  This field is
	// present if the mask bit is set to 1 and is absent if the mask bit
	// is set to 0.  See Section 5.3 for further information on client-
	// to-server masking.
	MaskingKey []byte

	// The "Extension data" is 0 bytes unless an extension has been
	// negotiated.  Any extension MUST specify the length of the
	// "Extension data", or how that length may be calculated, and how
	// the extension use MUST be negotiated during the opening handshake.
	// If present, the "Extension data" is included in the total payload
	// length.
	ExtensionData []byte

	// Arbitrary "Application data", taking up the remainder of the frame
	// after any "Extension data".  The length of the "Application data"
	// is equal to the payload length minus the length of the "Extension
	// data".
	ApplicationData []byte
	// contains filtered or unexported fields
}

func (*Frame) PayloadLength

func (f *Frame) PayloadLength() uint64

PayloadLength gives the length of the payload in a frame. This method always returns the uint64 type

type Opcode

type Opcode string

Defines the interpretation of the "Payload data". If an unknown opcode is received, the receiving endpoint MUST _Fail the WebSocket Connection_. The following values are defined.

var (
	// ContinuationFrame is the opcode send for fragments.
	// If the message length is greater than the fragmentationLimit of the opener,
	// the subsequent frames of the message will carry this opcode.
	ContinuationFrame Opcode = "continuation frame"

	// TextFrame is the opcode sent for text fragments.
	// In case of fragmented text messages, the first frame will carry this opcode.
	TextFrame Opcode = "text frame"

	// BinaryFrame is the opcode sent for binary fragments.
	// In case of fragmented binary messages, the first frame will carry this opcode.
	BinaryFrame Opcode = "binary frame"

	NonControlFrame Opcode = "non control frame"

	ConnectionClose Opcode = "connection close"

	Ping Opcode = "ping"

	Pong Opcode = "pong"

	ControlFrame Opcode = "control frame"
)

type Opener

type Opener interface {
	// Open will open a websocket connection, by upgrading the existing HTTP connection.
	// The opened websocket connection hijacks the existing http connection.
	Open(w http.ResponseWriter, r *http.Request, t WebsocketType) (Websocket, error)
}

Opener defines the methods possible by a websocket opener

type WSOpener

type WSOpener struct {
	// MaxBytes defines the maximum payload length of a frame.
	// If the message is bigger than this value, then the message is sent as fragments.
	MaxBytes int
}

func (*WSOpener) Open

Open will open a websocket connection, by upgrading the existing HTTP connection. The opened websocket connection hijacks the existing http connection.

type WebsockerServer

type WebsockerServer interface {
	// Send transports the message from the server to the the client.
	Send(ctx context.Context, message []byte) error

	// Receive waits for a message from the client.
	Receive(ctx context.Context) ([]byte, error)

	// Close closes an active websocket connection between the client and the server.
	Close(ctx context.Context) error
}

type Websocket

type Websocket struct {
	// contains filtered or unexported fields
}

func (*Websocket) Close

func (ws *Websocket) Close() error

func (*Websocket) Receive

func (ws *Websocket) Receive(ctx context.Context) ([]byte, error)

Receive waits for a message from the client.

func (*Websocket) Send

func (ws *Websocket) Send(ctx context.Context, data []byte) error

Send transports the message from the server to the the client.

type WebsocketType

type WebsocketType string
var (
	TextWebsocket WebsocketType = "text"

	BinaryWebsocket WebsocketType = "binary"
)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL