Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit b6caac6

Browse files
committedSep 21, 2019
Add WebSocket API
Closes #121
1 parent e09e295 commit b6caac6

31 files changed

+370
-33
lines changed
 

‎accept.go

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
// +build !js
2+
13
package websocket
24

35
import (

‎accept_test.go

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
// +build !js
2+
13
package websocket
24

35
import (

‎ci/wasm.sh

-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,5 @@ cd "$(git rev-parse --show-toplevel)"
66

77
GOOS=js GOARCH=wasm go vet ./...
88
go install golang.org/x/lint/golint
9-
# Get passing later.
109
#GOOS=js GOARCH=wasm golint -set_exit_status ./...
1110
GOOS=js GOARCH=wasm go test ./internal/wsjs

‎dial.go

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
// +build !js
2+
13
package websocket
24

35
import (

‎dial_test.go

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
// +build !js
2+
13
package websocket
24

35
import (

‎doc.go

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
// +build !js
2+
13
// Package websocket is a minimal and idiomatic implementation of the WebSocket protocol.
24
//
35
// https://tools.ietf.org/html/rfc6455

‎example_echo_test.go

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
// +build !js
2+
13
package websocket_test
24

35
import (

‎example_test.go

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
// +build !js
2+
13
package websocket_test
24

35
import (

‎export_test.go

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
// +build !js
2+
13
package websocket
24

35
import (

‎go.mod

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ require (
2222
golang.org/x/sys v0.0.0-20190919044723-0c1ff786ef13 // indirect
2323
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4
2424
golang.org/x/tools v0.0.0-20190920225731-5eefd052ad72
25+
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7
2526
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
2627
gotest.tools/gotestsum v0.3.5
2728
mvdan.cc/sh v2.6.4+incompatible

‎go.sum

+1
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxb
9797
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
9898
golang.org/x/tools v0.0.0-20190920225731-5eefd052ad72 h1:bw9doJza/SFBEweII/rHQh338oozWyiFsBRHtrflcws=
9999
golang.org/x/tools v0.0.0-20190920225731-5eefd052ad72/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
100+
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7 h1:9zdDQZ7Thm29KFXgAX/+yaf3eVbP7djjWp/dXAppNCc=
100101
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
101102
gopkg.in/airbrake/gobrake.v2 v2.0.9 h1:7z2uVWwn7oVeeugY1DtlPAy5H+KYgB1KeKTnqjNatLo=
102103
gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U=

‎header.go

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
// +build !js
2+
13
package websocket
24

35
import (

‎header_test.go

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
// +build !js
2+
13
package websocket
24

35
import (

‎internal/wsjs/wsjs.go

+28-23
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
package wsjs
66

77
import (
8-
"context"
98
"syscall/js"
109
)
1110

@@ -26,17 +25,17 @@ func handleJSError(err *error, onErr func()) {
2625
}
2726
}
2827

29-
func New(ctx context.Context, url string, protocols []string) (c *WebSocket, err error) {
28+
func New(url string, protocols []string) (c WebSocket, err error) {
3029
defer handleJSError(&err, func() {
31-
c = nil
30+
c = WebSocket{}
3231
})
3332

3433
jsProtocols := make([]interface{}, len(protocols))
3534
for i, p := range protocols {
3635
jsProtocols[i] = p
3736
}
3837

39-
c = &WebSocket{
38+
c = WebSocket{
4039
v: js.Global().Get("WebSocket").New(url, jsProtocols),
4140
}
4241

@@ -57,19 +56,25 @@ type WebSocket struct {
5756
v js.Value
5857
}
5958

60-
func (c *WebSocket) setBinaryType(typ string) {
59+
func (c WebSocket) setBinaryType(typ string) {
6160
c.v.Set("binaryType", string(typ))
6261
}
6362

64-
func (c *WebSocket) BufferedAmount() uint32 {
63+
func (c WebSocket) BufferedAmount() uint32 {
6564
return uint32(c.v.Get("bufferedAmount").Int())
6665
}
6766

68-
func (c *WebSocket) addEventListener(eventType string, fn func(e js.Value)) {
69-
c.v.Call("addEventListener", eventType, js.FuncOf(func(this js.Value, args []js.Value) interface{} {
67+
func (c WebSocket) addEventListener(eventType string, fn func(e js.Value)) func() {
68+
f := js.FuncOf(func(this js.Value, args []js.Value) interface{} {
7069
fn(args[0])
7170
return nil
72-
}))
71+
})
72+
c.v.Call("addEventListener", eventType, f)
73+
74+
return func() {
75+
c.v.Call("removeEventListener", eventType, f)
76+
f.Release()
77+
}
7378
}
7479

7580
type CloseEvent struct {
@@ -78,8 +83,8 @@ type CloseEvent struct {
7883
WasClean bool
7984
}
8085

81-
func (c *WebSocket) OnClose(fn func(CloseEvent)) {
82-
c.addEventListener("close", func(e js.Value) {
86+
func (c WebSocket) OnClose(fn func(CloseEvent)) (remove func()) {
87+
return c.addEventListener("close", func(e js.Value) {
8388
ce := CloseEvent{
8489
Code: uint16(e.Get("code").Int()),
8590
Reason: e.Get("reason").String(),
@@ -89,23 +94,23 @@ func (c *WebSocket) OnClose(fn func(CloseEvent)) {
8994
})
9095
}
9196

92-
func (c *WebSocket) OnError(fn func(e js.Value)) {
93-
c.addEventListener("error", fn)
97+
func (c WebSocket) OnError(fn func(e js.Value)) (remove func()) {
98+
return c.addEventListener("error", fn)
9499
}
95100

96101
type MessageEvent struct {
97-
Data []byte
102+
Data interface{}
98103
// There are more types to the interface but we don't use them.
99104
// See https://developer.mozilla.org/en-US/docs/Web/API/MessageEvent
100105
}
101106

102-
func (c *WebSocket) OnMessage(fn func(m MessageEvent)) {
103-
c.addEventListener("message", func(e js.Value) {
104-
var data []byte
107+
func (c WebSocket) OnMessage(fn func(m MessageEvent)) (remove func()) {
108+
return c.addEventListener("message", func(e js.Value) {
109+
var data interface{}
105110

106111
arrayBuffer := e.Get("data")
107112
if arrayBuffer.Type() == js.TypeString {
108-
data = []byte(arrayBuffer.String())
113+
data = arrayBuffer.String()
109114
} else {
110115
data = extractArrayBuffer(arrayBuffer)
111116
}
@@ -119,23 +124,23 @@ func (c *WebSocket) OnMessage(fn func(m MessageEvent)) {
119124
})
120125
}
121126

122-
func (c *WebSocket) OnOpen(fn func(e js.Value)) {
123-
c.addEventListener("open", fn)
127+
func (c WebSocket) OnOpen(fn func(e js.Value)) (remove func()) {
128+
return c.addEventListener("open", fn)
124129
}
125130

126-
func (c *WebSocket) Close(code int, reason string) (err error) {
131+
func (c WebSocket) Close(code int, reason string) (err error) {
127132
defer handleJSError(&err, nil)
128133
c.v.Call("close", code, reason)
129134
return err
130135
}
131136

132-
func (c *WebSocket) SendText(v string) (err error) {
137+
func (c WebSocket) SendText(v string) (err error) {
133138
defer handleJSError(&err, nil)
134139
c.v.Call("send", v)
135140
return err
136141
}
137142

138-
func (c *WebSocket) SendBytes(v []byte) (err error) {
143+
func (c WebSocket) SendBytes(v []byte) (err error) {
139144
defer handleJSError(&err, nil)
140145
c.v.Call("send", uint8Array(v))
141146
return err

‎internal/wsjs/wsjs_test.go

+1-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
package wsjs
44

55
import (
6-
"context"
76
"syscall/js"
87
"testing"
98
"time"
@@ -12,7 +11,7 @@ import (
1211
func TestWebSocket(t *testing.T) {
1312
t.Parallel()
1413

15-
c, err := New(context.Background(), "ws://localhost:8081", nil)
14+
c, err := New("ws://localhost:8081", nil)
1615
if err != nil {
1716
t.Fatal(err)
1817
}

‎netconn.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ func (c *netConn) Read(p []byte) (int, error) {
9393
}
9494

9595
if c.reader == nil {
96-
typ, r, err := c.c.Reader(c.readContext)
96+
typ, r, err := c.netConnReader(c.readContext)
9797
if err != nil {
9898
var ce CloseError
9999
if errors.As(err, &ce) && (ce.Code == StatusNormalClosure) || (ce.Code == StatusGoingAway) {

‎netconn_js.go

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// +build js
2+
3+
package websocket
4+
5+
import (
6+
"bytes"
7+
"context"
8+
"io"
9+
)
10+
11+
func (c *netConn) netConnReader(ctx context.Context) (MessageType, io.Reader, error) {
12+
typ, p, err := c.c.Read(ctx)
13+
if err != nil {
14+
return 0, nil, err
15+
}
16+
return typ, bytes.NewReader(p), nil
17+
}

‎netconn_normal.go

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// +build !js
2+
3+
package websocket
4+
5+
import (
6+
"context"
7+
"io"
8+
)
9+
10+
func (c *netConn) netConnReader(ctx context.Context) (MessageType, io.Reader, error) {
11+
return c.c.Reader(c.readContext)
12+
}

‎opcode.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package websocket
33
// opcode represents a WebSocket Opcode.
44
type opcode int
55

6-
//go:generate go run golang.org/x/tools/cmd/stringer -type=opcode
6+
//go:generate go run golang.org/x/tools/cmd/stringer -type=opcode -tags js
77

88
// opcode constants.
99
const (

‎opcode_string.go

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎websocket.go

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
// +build !js
2+
13
package websocket
24

35
import (

‎websocket_autobahn_python_test.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// This file contains the old autobahn test suite tests that use the
2-
// python binary. The approach is very clunky and slow so new tests
2+
// python binary. The approach is clunky and slow so new tests
33
// have been written in pure Go in websocket_test.go.
4+
// These have been kept for correctness purposes and are occasionally ran.
45
// +build autobahn-python
56

67
package websocket_test

‎websocket_bench_test.go

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
// +build !js
2+
13
package websocket_test
24

35
import (

0 commit comments

Comments
 (0)
Please sign in to comment.