2020-10-20 15:26:55 +00:00
|
|
|
/*
|
|
|
|
Package ws implements a client and server for the WebSocket protocol as
|
|
|
|
specified in RFC 6455.
|
|
|
|
|
|
|
|
The main purpose of this package is to provide simple low-level API for
|
|
|
|
efficient work with protocol.
|
|
|
|
|
|
|
|
Overview.
|
|
|
|
|
|
|
|
Upgrade to WebSocket (or WebSocket handshake) can be done in two ways.
|
|
|
|
|
|
|
|
The first way is to use `net/http` server:
|
|
|
|
|
2024-10-17 20:09:39 +00:00
|
|
|
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
conn, _, _, err := ws.UpgradeHTTP(r, w)
|
|
|
|
})
|
2020-10-20 15:26:55 +00:00
|
|
|
|
|
|
|
The second and much more efficient way is so-called "zero-copy upgrade". It
|
|
|
|
avoids redundant allocations and copying of not used headers or other request
|
|
|
|
data. User decides by himself which data should be copied.
|
|
|
|
|
2024-10-17 20:09:39 +00:00
|
|
|
ln, err := net.Listen("tcp", ":8080")
|
|
|
|
if err != nil {
|
|
|
|
// handle error
|
|
|
|
}
|
2020-10-20 15:26:55 +00:00
|
|
|
|
2024-10-17 20:09:39 +00:00
|
|
|
conn, err := ln.Accept()
|
|
|
|
if err != nil {
|
|
|
|
// handle error
|
|
|
|
}
|
2020-10-20 15:26:55 +00:00
|
|
|
|
2024-10-17 20:09:39 +00:00
|
|
|
handshake, err := ws.Upgrade(conn)
|
|
|
|
if err != nil {
|
|
|
|
// handle error
|
|
|
|
}
|
2020-10-20 15:26:55 +00:00
|
|
|
|
|
|
|
For customization details see `ws.Upgrader` documentation.
|
|
|
|
|
|
|
|
After WebSocket handshake you can work with connection in multiple ways.
|
|
|
|
That is, `ws` does not force the only one way of how to work with WebSocket:
|
|
|
|
|
2024-10-17 20:09:39 +00:00
|
|
|
header, err := ws.ReadHeader(conn)
|
|
|
|
if err != nil {
|
|
|
|
// handle err
|
|
|
|
}
|
2020-10-20 15:26:55 +00:00
|
|
|
|
2024-10-17 20:09:39 +00:00
|
|
|
buf := make([]byte, header.Length)
|
|
|
|
_, err := io.ReadFull(conn, buf)
|
|
|
|
if err != nil {
|
|
|
|
// handle err
|
|
|
|
}
|
2020-10-20 15:26:55 +00:00
|
|
|
|
2024-10-17 20:09:39 +00:00
|
|
|
resp := ws.NewBinaryFrame([]byte("hello, world!"))
|
|
|
|
if err := ws.WriteFrame(conn, frame); err != nil {
|
|
|
|
// handle err
|
|
|
|
}
|
2020-10-20 15:26:55 +00:00
|
|
|
|
|
|
|
As you can see, it stream friendly:
|
|
|
|
|
2024-10-17 20:09:39 +00:00
|
|
|
const N = 42
|
2020-10-20 15:26:55 +00:00
|
|
|
|
2024-10-17 20:09:39 +00:00
|
|
|
ws.WriteHeader(ws.Header{
|
|
|
|
Fin: true,
|
|
|
|
Length: N,
|
|
|
|
OpCode: ws.OpBinary,
|
|
|
|
})
|
2020-10-20 15:26:55 +00:00
|
|
|
|
2024-10-17 20:09:39 +00:00
|
|
|
io.CopyN(conn, rand.Reader, N)
|
2020-10-20 15:26:55 +00:00
|
|
|
|
|
|
|
Or:
|
|
|
|
|
2024-10-17 20:09:39 +00:00
|
|
|
header, err := ws.ReadHeader(conn)
|
|
|
|
if err != nil {
|
|
|
|
// handle err
|
|
|
|
}
|
2020-10-20 15:26:55 +00:00
|
|
|
|
2024-10-17 20:09:39 +00:00
|
|
|
io.CopyN(ioutil.Discard, conn, header.Length)
|
2020-10-20 15:26:55 +00:00
|
|
|
|
|
|
|
For more info see the documentation.
|
|
|
|
*/
|
|
|
|
package ws
|