Package websocket implements a client and server for the WebSocket protocol as specified in RFC 6455.
Note: This package currently lacks some features found in more actively maintained alternatives like github.com/gorilla/websocket and github.com/coder/websocket.
import "golang.org/x/net/websocket"const (
ProtocolVersionHybi13 = 13
ProtocolVersionHybi = ProtocolVersionHybi13
SupportedProtocolVersion = "13"
ContinuationFrame = 0
TextFrame = 1
BinaryFrame = 2
CloseFrame = 8
PingFrame = 9
PongFrame = 10
UnknownFrame = 255
DefaultMaxPayloadBytes = 32 << 20 // 32MB
)var (
ErrBadMaskingKey = &ProtocolError{"bad masking key"}
ErrBadPongMessage = &ProtocolError{"bad pong message"}
ErrBadClosingStatus = &ProtocolError{"bad closing status"}
ErrUnsupportedExtensions = &ProtocolError{"unsupported extensions"}
ErrNotImplemented = &ProtocolError{"not implemented"}
)
var (
ErrBadProtocolVersion = &ProtocolError{"bad protocol version"}
ErrBadScheme = &ProtocolError{"bad scheme"}
ErrBadStatus = &ProtocolError{"bad status"}
ErrBadUpgrade = &ProtocolError{"missing or bad upgrade"}
ErrBadWebSocketOrigin = &ProtocolError{"missing or bad WebSocket-Origin"}
ErrBadWebSocketLocation = &ProtocolError{"missing or bad WebSocket-Location"}
ErrBadWebSocketProtocol = &ProtocolError{"missing or bad WebSocket-Protocol"}
ErrBadWebSocketVersion = &ProtocolError{"missing or bad WebSocket Version"}
ErrChallengeResponse = &ProtocolError{"mismatch challenge/response"}
ErrBadFrame = &ProtocolError{"bad frame"}
ErrBadFrameBoundary = &ProtocolError{"not on frame boundary"}
ErrNotWebSocket = &ProtocolError{"not websocket protocol"}
ErrBadRequestMethod = &ProtocolError{"bad method"}
ErrNotSupported = &ProtocolError{"not supported"}
)
var ErrFrameTooLarge = errors.New("websocket: frame payload size exceeds limit")
// JSON is a codec to send/receive JSON data
var JSON = Codec{jsonMarshal, jsonUnmarshal}
// Message is a codec to send/receive text/binary data
var Message = Codec{msgMarshal, msgUnmarshal}// Conn represents a WebSocket connection
type Conn struct {
// MaxPayloadBytes limits the size of received frame payload
MaxPayloadBytes int
// Has unexported fields
}
func Dial(url_, protocol, origin string) (ws *Conn, err error)
func DialConfig(config *Config) (ws *Conn, err error)
func NewClient(config *Config, rwc io.ReadWriteCloser) (ws *Conn, err error)
func (ws *Conn) Close() error
func (ws *Conn) IsClientConn() bool
func (ws *Conn) IsServerConn() bool
func (ws *Conn) LocalAddr() net.Addr
func (ws *Conn) RemoteAddr() net.Addr
func (ws *Conn) SetDeadline(t time.Time) error
func (ws *Conn) SetReadDeadline(t time.Time) error
func (ws *Conn) SetWriteDeadline(t time.Time) error
func (ws *Conn) Read(msg []byte) (n int, err error)
func (ws *Conn) Write(msg []byte) (n int, err error)
func (ws *Conn) Request() *http.Request
func (ws *Conn) Config() *Config
func (ws *Conn) PayloadType() byte// Config is a WebSocket configuration
type Config struct {
Location *url.URL // WebSocket URL
Origin *url.URL // Origin URL
Protocol []string // WebSocket subprotocols
Version int // WebSocket protocol version
TlsConfig *tls.Config // TLS configuration
Header http.Header // Additional header fields
Dialer *net.Dialer // Network dialer
// Has unexported fields
}
func NewConfig(server, origin string) (config *Config, err error)// Handler is a WebSocket server handler
type Handler func(*Conn)
func (h Handler) ServeHTTP(w http.ResponseWriter, req *http.Request)// Server represents a WebSocket server
type Server struct {
Config Config
Handler Handler
Handshake func(*Config, *http.Request) error
}
func (s Server) ServeHTTP(w http.ResponseWriter, req *http.Request)// Codec represents a WebSocket codec
type Codec struct {
// Has unexported fields
}
func (cd Codec) Send(ws *Conn, v interface{}) error
func (cd Codec) Receive(ws *Conn, v interface{}) error// ProtocolError represents a WebSocket protocol error
type ProtocolError struct {
ErrorString string
}
func (err *ProtocolError) Error() string// DialError is an error that occurs while dialling a websocket server
type DialError struct {
*Config
Err error
}
func (e *DialError) Error() stringimport "golang.org/x/net/websocket"
func connectWebSocket() error {
origin := "http://localhost/"
url := "ws://localhost:8080/ws"
ws, err := websocket.Dial(url, "", origin)
if err != nil {
return err
}
defer ws.Close()
// Send text message
if err := websocket.Message.Send(ws, "Hello, WebSocket!"); err != nil {
return err
}
// Receive text message
var msg string
if err := websocket.Message.Receive(ws, &msg); err != nil {
return err
}
fmt.Printf("Received: %s\n", msg)
return nil
}func startWebSocketServer() error {
http.Handle("/ws", websocket.Handler(echoHandler))
return http.ListenAndServe(":8080", nil)
}
func echoHandler(ws *websocket.Conn) {
defer ws.Close()
for {
var msg string
if err := websocket.Message.Receive(ws, &msg); err != nil {
break
}
fmt.Printf("Received: %s\n", msg)
if err := websocket.Message.Send(ws, msg); err != nil {
break
}
}
}type Message struct {
Type string `json:"type"`
Content string `json:"content"`
}
func sendJSON(ws *websocket.Conn) error {
msg := Message{
Type: "greeting",
Content: "Hello, JSON!",
}
return websocket.JSON.Send(ws, msg)
}
func receiveJSON(ws *websocket.Conn) (*Message, error) {
var msg Message
if err := websocket.JSON.Receive(ws, &msg); err != nil {
return nil, err
}
return &msg, nil
}func connectWithConfig() error {
config, err := websocket.NewConfig("ws://localhost:8080/ws", "http://localhost/")
if err != nil {
return err
}
config.Protocol = []string{"chat", "superchat"}
config.Header = http.Header{
"Authorization": []string{"Bearer token123"},
}
ws, err := websocket.DialConfig(config)
if err != nil {
return err
}
defer ws.Close()
// Use connection
return nil
}func sendBinary(ws *websocket.Conn, data []byte) error {
return websocket.Message.Send(ws, data)
}
func receiveBinary(ws *websocket.Conn) ([]byte, error) {
var data []byte
if err := websocket.Message.Receive(ws, &data); err != nil {
return nil, err
}
return data, nil
}func startCustomHandshakeServer() error {
server := &websocket.Server{
Handler: echoHandler,
Handshake: func(config *websocket.Config, req *http.Request) error {
// Custom handshake logic
token := req.Header.Get("Authorization")
if token != "Bearer valid-token" {
return fmt.Errorf("unauthorized")
}
return nil
},
}
http.Handle("/ws", server)
return http.ListenAndServe(":8080", nil)
}func limitedReceive(ws *websocket.Conn) error {
// Limit payload to 1MB
ws.MaxPayloadBytes = 1 << 20
var msg string
return websocket.Message.Receive(ws, &msg)
}