Skip to content

Commit ad89367

Browse files
authored
Merge pull request #68 from nhooyr/docs
General Improvements
2 parents c7ee8af + 1943020 commit ad89367

20 files changed

+433
-219
lines changed

.github/ISSUE_TEMPLATE/bug_report.md

Lines changed: 0 additions & 24 deletions
This file was deleted.

.github/ISSUE_TEMPLATE/feature_request.md

Lines changed: 0 additions & 20 deletions
This file was deleted.

README.md

Lines changed: 24 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
websocket is a minimal and idiomatic WebSocket library for Go.
66

7-
At minimum Go 1.12 is required as websocket uses a new [feature](https://github.com/golang/go/issues/26937#issuecomment-415855861) in net/http
7+
Go 1.12 is required as it uses a new [feature](https://github.com/golang/go/issues/26937#issuecomment-415855861) in net/http
88
to perform WebSocket handshakes.
99

1010
This library is not final and the API is subject to change.
@@ -19,13 +19,12 @@ go get nhooyr.io/websocket
1919

2020
## Features
2121

22-
- Full support of the WebSocket protocol
23-
- Zero dependencies outside of the stdlib
24-
- Very minimal and carefully considered API
25-
- context.Context is first class
26-
- net/http is used for WebSocket dials and upgrades
22+
- Minimal yet pragmatic API
23+
- First class context.Context support
2724
- Thoroughly tested, fully passes the [autobahn-testsuite](https://github.com/crossbario/autobahn-testsuite)
28-
- All returned errors include detailed context
25+
- Concurrent writes
26+
- Zero dependencies outside of the stdlib for the core library
27+
- JSON and ProtoBuf helpers in the wsjson and wspb subpackages
2928

3029
## Roadmap
3130

@@ -97,45 +96,45 @@ c.Close(websocket.StatusNormalClosure, "")
9796

9897
## Design considerations
9998

100-
- Minimal API is easier to maintain and for others to learn
99+
- Minimal API is easier to maintain and learn
101100
- Context based cancellation is more ergonomic and robust than setting deadlines
102-
- No pings or pongs because TCP keep alives work fine for HTTP/1.1 and they do not make
101+
- No ping support because TCP keep alives work fine for HTTP/1.1 and they do not make
103102
sense with HTTP/2 (see #1)
104103
- net.Conn is never exposed as WebSocket's over HTTP/2 will not have a net.Conn.
105-
- Functional options make the API very clean and easy to extend
104+
- Structures are nicer than functional options, see [google/go-cloud#908](https://github.com/google/go-cloud/issues/908#issuecomment-445034143)
106105
- Using net/http's Client for dialing means we do not have to reinvent dialing hooks
107-
and configurations. Just pass in a custom net/http client if you want custom dialing.
106+
and configurations like other WebSocket libraries
108107

109108
## Comparison
110109

111110
While I believe nhooyr/websocket has a better API than existing libraries,
112111
both gorilla/websocket and gobwas/ws were extremely useful in implementing the
113-
WebSocket protocol correctly so big thanks to the authors of both. In particular,
112+
WebSocket protocol correctly so **big thanks** to the authors of both. In particular,
114113
I made sure to go through the issue tracker of gorilla/websocket to make sure
115-
I implemented details correctly.
114+
I implemented details correctly and understood how people were using the package
115+
in production.
116116

117117
### gorilla/websocket
118118

119119
https://github.com/gorilla/websocket
120120

121-
This package is the community standard but it is very old and over time
122-
has accumulated cruft. There are many ways to do the same thing and the API
123-
is not clear. Just compare the godoc of
121+
This package is the community standard but it is 6 years old and over time
122+
has accumulated cruft. There are many ways to do the same thing, usage is not clear
123+
and there are some rough edges. Just compare the godoc of
124124
[nhooyr/websocket](godoc.org/github.com/nhooyr/websocket) side by side with
125125
[gorilla/websocket](godoc.org/github.com/gorilla/websocket).
126126

127127
The API for nhooyr/websocket has been designed such that there is only one way to do things
128-
which makes using it correctly and safely much easier.
129-
130-
In terms of lines of code, this library is around 2000 whereas gorilla/websocket is
131-
at 7000. So while the API for nhooyr/websocket is simpler, the implementation is also
132-
significantly simpler and easier to test which reduces the surface are of bugs.
128+
which makes it easy to use correctly.
133129

134130
Furthermore, nhooyr/websocket has support for newer Go idioms such as context.Context and
135131
also uses net/http's Client and ResponseWriter directly for WebSocket handshakes.
136132
gorilla/websocket writes its handshakes directly to a net.Conn which means
137133
it has to reinvent hooks for TLS and proxying and prevents support of HTTP/2.
138134

135+
Another advantage of nhooyr/websocket is that it supports multiple concurrent writers out
136+
of the box.
137+
139138
### x/net/websocket
140139

141140
https://godoc.org/golang.org/x/net/websocket
@@ -149,12 +148,12 @@ See https://github.com/golang/go/issues/18152
149148
https://github.com/gobwas/ws
150149

151150
This library has an extremely flexible API but that comes at the cost of usability
152-
and clarity. Its not clear what the best way to do anything is.
151+
and clarity.
153152

154153
This library is fantastic in terms of performance. The author put in significant
155154
effort to ensure its speed and I have applied as many of its optimizations as
156-
I could into nhooyr/websocket.
155+
I could into nhooyr/websocket. Definitely check out his fantastic [blog post](https://medium.freecodecamp.org/million-websockets-and-go-cc58418460bb) about performant WebSocket servers.
157156

158157
If you want a library that gives you absolute control over everything, this is the library,
159-
but for most users, the API provided by nhooyr/websocket will definitely fit better as it will
160-
be just as performant but much easier to use correctly.
158+
but for most users, the API provided by nhooyr/websocket will fit better as it is just as
159+
performant but much easier to use correctly and idiomatic.

accept.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ type AcceptOptions struct {
3434
// The only time you need this is if your javascript is running on a different domain
3535
// than your WebSocket server.
3636
// Please think carefully about whether you really need this option before you use it.
37-
// If you do, remember if you store secure data in cookies, you wil need to verify the
38-
// Origin header.
37+
// If you do, remember that if you store secure data in cookies, you wil need to verify the
38+
// Origin header yourself otherwise you are exposing yourself to a CSRF attack.
3939
InsecureSkipVerify bool
4040
}
4141

bench_test.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -85,14 +85,14 @@ func benchConn(b *testing.B, stream bool) {
8585
})
8686
}
8787

88-
// runN(32)
89-
// runN(128)
90-
// runN(512)
91-
// runN(1024)
88+
runN(32)
89+
runN(128)
90+
runN(512)
91+
runN(1024)
9292
runN(4096)
9393
runN(16384)
94-
// runN(65536)
95-
// runN(131072)
94+
runN(65536)
95+
runN(131072)
9696

9797
c.Close(websocket.StatusNormalClosure, "")
9898
})

ci/bench/entrypoint.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ go test --vet=off --run=^$ -bench=. \
99
-memprofile=profs/mem \
1010
-blockprofile=profs/block \
1111
-mutexprofile=profs/mutex \
12-
./...
12+
.
1313

1414
set +x
1515
echo

ci/test/entrypoint.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@ source ci/lib.sh || exit 1
55
mkdir -p profs
66

77
set +x
8+
echo
89
echo "this step includes benchmarks for race detection and coverage purposes
910
but the numbers will be misleading. please see the bench step for more
1011
accurate numbers"
12+
echo
1113
set -x
1214

1315
go test -race -coverprofile=profs/coverage --vet=off -bench=. ./...

dial.go

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ type DialOptions struct {
2222
// http.Transport does this correctly.
2323
HTTPClient *http.Client
2424

25-
// Header specifies the HTTP headers included in the handshake request.
26-
Header http.Header
25+
// HTTPHeader specifies the HTTP headers included in the handshake request.
26+
HTTPHeader http.Header
2727

2828
// Subprotocols lists the subprotocols to negotiate with the server.
2929
Subprotocols []string
@@ -47,8 +47,11 @@ func dial(ctx context.Context, u string, opts DialOptions) (_ *Conn, _ *http.Res
4747
if opts.HTTPClient == nil {
4848
opts.HTTPClient = http.DefaultClient
4949
}
50-
if opts.Header == nil {
51-
opts.Header = http.Header{}
50+
if opts.HTTPClient.Timeout > 0 {
51+
return nil, nil, xerrors.Errorf("please use context for cancellation instead of http.Client.Timeout; see issue nhooyr.io/websocket#67")
52+
}
53+
if opts.HTTPHeader == nil {
54+
opts.HTTPHeader = http.Header{}
5255
}
5356

5457
parsedURL, err := url.Parse(u)
@@ -67,7 +70,7 @@ func dial(ctx context.Context, u string, opts DialOptions) (_ *Conn, _ *http.Res
6770

6871
req, _ := http.NewRequest("GET", parsedURL.String(), nil)
6972
req = req.WithContext(ctx)
70-
req.Header = opts.Header
73+
req.Header = opts.HTTPHeader
7174
req.Header.Set("Connection", "Upgrade")
7275
req.Header.Set("Upgrade", "websocket")
7376
req.Header.Set("Sec-WebSocket-Version", "13")

doc.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,14 @@
22
//
33
// See https://tools.ietf.org/html/rfc6455
44
//
5+
// Please see https://nhooyr.io/websocket for overview docs and a
6+
// comparison with existing implementations.
7+
//
8+
// Conn, Dial, and Accept are the main entrypoints into this package. Use Dial to dial
9+
// a WebSocket server, Accept to accept a WebSocket client dial and then Conn to interact
10+
// with the resulting WebSocket connections.
11+
//
512
// The echo example is the best way to understand how to correctly use the library.
613
//
7-
// Please see https://nhooyr.io/websocket for detailed design docs and a comparison with existing
8-
// libraries.
14+
// The wsjson and wspb packages contain helpers for JSON and ProtoBuf messages.
915
package websocket

docs/CONTRIBUTING.md renamed to docs/contributing.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
1-
# Contributing Guidelines
1+
# Contributing
2+
3+
## Issues
4+
5+
Please be as descriptive as possible with your description.
6+
7+
## Pull requests
28

39
Please split up changes into several small descriptive commits.
410

0 commit comments

Comments
 (0)