gws

package module
v1.1.2 Latest Latest
Warning

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

Go to latest
Published: Jan 4, 2023 License: MIT Imports: 16 Imported by: 64

README

gws

minimal websocket server
Highlight
  • websocket event api
  • write in batch and flush
  • no dependency
  • zero goroutine to control websocket
  • fully passes the WebSocket autobahn-testsuite
Attention
  • It's designed for api server, do not write big message
  • It's recommended not to enable data compression in the intranet
  • WebSocket Events are emitted synchronously, manage goroutines yourself
Interface
type Event interface {
	OnOpen(socket *Conn)
	OnError(socket *Conn, err error)
	OnClose(socket *Conn, message *Message)
	OnMessage(socket *Conn, message *Message)
	OnPing(socket *Conn, message *Message)
	OnPong(socket *Conn, message *Message)
}
Quick Start
package main

import (
	"context"
	"fmt"
	"github.com/lxzan/gws"
	"net/http"
)

func main() {
	var upgrader = gws.Upgrader{CompressEnabled: true, MaxContentLength: 32 * 1024 * 1024}
	var handler = new(WebSocket)

	http.HandleFunc("/connect", func(writer http.ResponseWriter, request *http.Request) {
		socket, err := upgrader.Upgrade(context.Background(), writer, request, handler)
		if err != nil {
			return
		}

		defer socket.Close()
		socket.Listen()
	})

	_ = http.ListenAndServe(":3000", nil)
}

type WebSocket struct{}

func (c *WebSocket) OnClose(socket *gws.Conn, message *gws.Message) {
	fmt.Printf("onclose: code=%d, payload=%s\n", message.Code(), string(message.Bytes()))
	message.Close()
}

func (c *WebSocket) OnError(socket *gws.Conn, err error) {
	fmt.Printf("onerror: err=%s\n", err.Error())
}

func (c *WebSocket) OnOpen(socket *gws.Conn) {
	println("connected")
}

func (c *WebSocket) OnMessage(socket *gws.Conn, message *gws.Message) {
	socket.WriteMessage(message.Typ(), message.Bytes())
	message.Close()
}

func (c *WebSocket) OnPing(socket *gws.Conn, message *gws.Message) {
	fmt.Printf("onping: payload=%s\n", string(message.Bytes()))
	socket.WritePong(message.Bytes())
	message.Close()
}

func (c *WebSocket) OnPong(socket *gws.Conn, message *gws.Message) {}

Documentation

Index

Constants

View Source
const (
	DefaultHandshakeTimeout = 5 * time.Second
	DefaultReadTimeout      = 30 * time.Second
	DefaultWriteTimeout     = 30 * time.Second
	DefaultCompressLevel    = flate.BestSpeed
	DefaultMaxContentLength = 1 * 1024 * 1024 // 1MiB
)

Variables

View Source
var (
	ErrCheckOrigin = errors.New("check origin error")
	ErrHandshake   = errors.New("handshake error")
)

Functions

This section is empty.

Types

type CloseCode added in v1.1.0

type CloseCode uint16
const (
	// 正常关闭; 无论为何目的而创建, 该链接都已成功完成任务.
	CloseNormalClosure CloseCode = 1000

	// 终端离开, 可能因为服务端错误, 也可能因为浏览器正从打开连接的页面跳转离开.
	CloseGoingAway CloseCode = 1001

	// 由于协议错误而中断连接.
	CloseProtocolError CloseCode = 1002

	// 由于接收到不允许的数据类型而断开连接 (如仅接收文本数据的终端接收到了二进制数据).
	CloseUnsupported CloseCode = 1003

	// 保留. 表示没有收到预期的状态码.
	CloseNoStatusReceived CloseCode = 1005

	// 保留. 用于期望收到状态码时连接非正常关闭 (也就是说, 没有发送关闭帧).
	CloseAbnormalClosure CloseCode = 1006

	// 由于收到了格式不符的数据而断开连接 (如文本消息中包含了非 UTF-8 数据).
	CloseUnsupportedData CloseCode = 1007

	// 由于收到不符合约定的数据而断开连接. 这是一个通用状态码, 用于不适合使用 1003 和 1009 状态码的场景.
	ClosePolicyViolation CloseCode = 1008

	// 由于收到过大的数据帧而断开连接.
	CloseMessageTooLarge CloseCode = 1009

	// 客户端期望服务器商定一个或多个拓展, 但服务器没有处理, 因此客户端断开连接.
	CloseMissingExtension CloseCode = 1010

	// 客户端由于遇到没有预料的情况阻止其完成请求, 因此服务端断开连接.
	CloseInternalServerErr CloseCode = 1011

	// 服务器由于重启而断开连接. [Ref]
	CloseServiceRestart CloseCode = 1012

	// 服务器由于临时原因断开连接, 如服务器过载因此断开一部分客户端连接. [Ref]
	CloseTryAgainLater CloseCode = 1013

	// 保留. 表示连接由于无法完成 TLS 握手而关闭 (例如无法验证服务器证书).
	CloseTLSHandshake CloseCode = 1015
)

func (CloseCode) Bytes added in v1.1.0

func (c CloseCode) Bytes() []byte

func (CloseCode) Error added in v1.1.0

func (c CloseCode) Error() string

func (CloseCode) Uint16 added in v1.1.0

func (c CloseCode) Uint16() uint16

type Conn

type Conn struct {

	// Concurrent Variable
	// store session information
	*Storage
	// contains filtered or unexported fields
}

func (*Conn) Close

func (c *Conn) Close()

Close 关闭TCP连接

func (*Conn) FlushWriter added in v1.1.0

func (c *Conn) FlushWriter()

FlushWriter 刷新写入缓冲区 flush write buffer

func (*Conn) Listen added in v1.1.2

func (c *Conn) Listen()

Listen listening to websocket messages through a dead loop 通过死循环监听websocket消息

func (*Conn) LocalAddr added in v1.0.1

func (c *Conn) LocalAddr() net.Addr

func (*Conn) RemoteAddr added in v1.0.1

func (c *Conn) RemoteAddr() net.Addr

func (*Conn) SetDeadline

func (c *Conn) SetDeadline(t time.Time)

SetDeadline sets deadline

func (*Conn) SetReadDeadline added in v1.1.2

func (c *Conn) SetReadDeadline(t time.Time)

SetReadDeadline sets read deadline

func (*Conn) SetWriteDeadline added in v1.1.2

func (c *Conn) SetWriteDeadline(t time.Time)

SetWriteDeadline sets write deadline

func (*Conn) WriteBatch added in v1.1.0

func (c *Conn) WriteBatch(opcode Opcode, payload []byte)

WriteBatch write message in batch, call FlushWriter in the end 批量写入消息,最后一次写入后需要调用FlushWriter

func (*Conn) WriteClose

func (c *Conn) WriteClose(code CloseCode, reason []byte)

WriteClose write close frame 发送关闭帧

func (*Conn) WriteMessage added in v1.1.0

func (c *Conn) WriteMessage(opcode Opcode, payload []byte)

WriteMessage write text/binary message text message must be utf8 encoding 发送文本/二进制消息, 文本消息必须是utf8编码

func (*Conn) WritePing

func (c *Conn) WritePing(payload []byte)

WritePing write ping frame

func (*Conn) WritePong

func (c *Conn) WritePong(payload []byte)

WritePong write pong frame

type Event added in v1.1.2

type Event interface {
	OnOpen(socket *Conn)
	OnError(socket *Conn, err error)
	OnClose(socket *Conn, message *Message)
	OnMessage(socket *Conn, message *Message)
	OnPing(socket *Conn, message *Message)
	OnPong(socket *Conn, message *Message)
}

type Message

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

func (*Message) Bytes

func (c *Message) Bytes() []byte

Bytes get message content

func (*Message) Close

func (c *Message) Close()

Close recycle buffer

func (*Message) Code added in v1.1.2

func (c *Message) Code() CloseCode

Code get close code only close frame has the code

func (*Message) Read added in v1.1.0

func (c *Message) Read(p []byte) (n int, err error)

func (*Message) Typ added in v1.1.0

func (c *Message) Typ() Opcode

Typ get message type

type Opcode

type Opcode uint8
const (
	OpcodeContinuation    Opcode = 0x0
	OpcodeText            Opcode = 0x1
	OpcodeBinary          Opcode = 0x2
	OpcodeCloseConnection Opcode = 0x8
	OpcodePing            Opcode = 0x9
	OpcodePong            Opcode = 0xA
)

func (Opcode) IsDataFrame added in v1.1.2

func (c Opcode) IsDataFrame() bool

type Request

type Request struct {
	*http.Request // http request
	*Storage      // store user session
}

type Storage added in v1.1.2

type Storage = internal.Map

type Upgrader

type Upgrader struct {
	// whether to compress data, dv = false
	CompressEnabled bool

	// compress level eg: flate.BestSpeed
	CompressLevel int

	// websocket  handshake timeout, dv=3s
	HandshakeTimeout time.Duration

	// max message size, dv=1024*1024 (1MiB)
	MaxContentLength int

	// read frame timeout, dv=5s
	ReadTimeout time.Duration

	// write frame timeout, dv=5s
	WriteTimeout time.Duration

	// filter user request
	CheckOrigin func(r *Request) bool
}

func (*Upgrader) Upgrade

func (c *Upgrader) Upgrade(ctx context.Context, w http.ResponseWriter, r *http.Request, handler Event) (*Conn, error)

http protocol upgrade to websocket

Directories

Path Synopsis
examples
bench command
testsuite command

Jump to

Keyboard shortcuts

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