1
1
// +build js
2
2
3
3
// Package wsjs implements typed access to the browser javascript WebSocket API.
4
+ //
4
5
// https://developer.mozilla.org/en-US/docs/Web/API/WebSocket
5
6
package wsjs
6
7
7
8
import (
8
- "context"
9
9
"syscall/js"
10
10
)
11
11
@@ -26,17 +26,18 @@ func handleJSError(err *error, onErr func()) {
26
26
}
27
27
}
28
28
29
- func New (ctx context.Context , url string , protocols []string ) (c * WebSocket , err error ) {
29
+ // New is a wrapper around the javascript WebSocket constructor.
30
+ func New (url string , protocols []string ) (c WebSocket , err error ) {
30
31
defer handleJSError (& err , func () {
31
- c = nil
32
+ c = WebSocket {}
32
33
})
33
34
34
35
jsProtocols := make ([]interface {}, len (protocols ))
35
36
for i , p := range protocols {
36
37
jsProtocols [i ] = p
37
38
}
38
39
39
- c = & WebSocket {
40
+ c = WebSocket {
40
41
v : js .Global ().Get ("WebSocket" ).New (url , jsProtocols ),
41
42
}
42
43
@@ -49,6 +50,7 @@ func New(ctx context.Context, url string, protocols []string) (c *WebSocket, err
49
50
return c , nil
50
51
}
51
52
53
+ // WebSocket is a wrapper around a javascript WebSocket object.
52
54
type WebSocket struct {
53
55
Extensions string
54
56
Protocol string
@@ -57,29 +59,33 @@ type WebSocket struct {
57
59
v js.Value
58
60
}
59
61
60
- func (c * WebSocket ) setBinaryType (typ string ) {
62
+ func (c WebSocket ) setBinaryType (typ string ) {
61
63
c .v .Set ("binaryType" , string (typ ))
62
64
}
63
65
64
- func (c * WebSocket ) BufferedAmount () uint32 {
65
- return uint32 (c .v .Get ("bufferedAmount" ).Int ())
66
- }
67
-
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 {} {
66
+ func (c WebSocket ) addEventListener (eventType string , fn func (e js.Value )) func () {
67
+ f := js .FuncOf (func (this js.Value , args []js.Value ) interface {} {
70
68
fn (args [0 ])
71
69
return nil
72
- }))
70
+ })
71
+ c .v .Call ("addEventListener" , eventType , f )
72
+
73
+ return func () {
74
+ c .v .Call ("removeEventListener" , eventType , f )
75
+ f .Release ()
76
+ }
73
77
}
74
78
79
+ // CloseEvent is the type passed to a WebSocket close handler.
75
80
type CloseEvent struct {
76
81
Code uint16
77
82
Reason string
78
83
WasClean bool
79
84
}
80
85
81
- func (c * WebSocket ) OnClose (fn func (CloseEvent )) {
82
- c .addEventListener ("close" , func (e js.Value ) {
86
+ // OnClose registers a function to be called when the WebSocket is closed.
87
+ func (c WebSocket ) OnClose (fn func (CloseEvent )) (remove func ()) {
88
+ return c .addEventListener ("close" , func (e js.Value ) {
83
89
ce := CloseEvent {
84
90
Code : uint16 (e .Get ("code" ).Int ()),
85
91
Reason : e .Get ("reason" ).String (),
@@ -89,23 +95,29 @@ func (c *WebSocket) OnClose(fn func(CloseEvent)) {
89
95
})
90
96
}
91
97
92
- func (c * WebSocket ) OnError (fn func (e js.Value )) {
93
- c .addEventListener ("error" , fn )
98
+ // OnError registers a function to be called when there is an error
99
+ // with the WebSocket.
100
+ func (c WebSocket ) OnError (fn func (e js.Value )) (remove func ()) {
101
+ return c .addEventListener ("error" , fn )
94
102
}
95
103
104
+ // MessageEvent is the type passed to a message handler.
96
105
type MessageEvent struct {
97
- Data []byte
98
- // There are more types to the interface but we don't use them.
106
+ // string or []byte.
107
+ Data interface {}
108
+
109
+ // There are more fields to the interface but we don't use them.
99
110
// See https://developer.mozilla.org/en-US/docs/Web/API/MessageEvent
100
111
}
101
112
102
- func (c * WebSocket ) OnMessage (fn func (m MessageEvent )) {
103
- c .addEventListener ("message" , func (e js.Value ) {
104
- var data []byte
113
+ // OnMessage registers a function to be called when the websocket receives a message.
114
+ func (c WebSocket ) OnMessage (fn func (m MessageEvent )) (remove func ()) {
115
+ return c .addEventListener ("message" , func (e js.Value ) {
116
+ var data interface {}
105
117
106
118
arrayBuffer := e .Get ("data" )
107
119
if arrayBuffer .Type () == js .TypeString {
108
- data = [] byte ( arrayBuffer .String () )
120
+ data = arrayBuffer .String ()
109
121
} else {
110
122
data = extractArrayBuffer (arrayBuffer )
111
123
}
@@ -119,23 +131,29 @@ func (c *WebSocket) OnMessage(fn func(m MessageEvent)) {
119
131
})
120
132
}
121
133
122
- func (c * WebSocket ) OnOpen (fn func (e js.Value )) {
123
- c .addEventListener ("open" , fn )
134
+ // OnOpen registers a function to be called when the websocket is opened.
135
+ func (c WebSocket ) OnOpen (fn func (e js.Value )) (remove func ()) {
136
+ return c .addEventListener ("open" , fn )
124
137
}
125
138
126
- func (c * WebSocket ) Close (code int , reason string ) (err error ) {
139
+ // Close closes the WebSocket with the given code and reason.
140
+ func (c WebSocket ) Close (code int , reason string ) (err error ) {
127
141
defer handleJSError (& err , nil )
128
142
c .v .Call ("close" , code , reason )
129
143
return err
130
144
}
131
145
132
- func (c * WebSocket ) SendText (v string ) (err error ) {
146
+ // SendText sends the given string as a text message
147
+ // on the WebSocket.
148
+ func (c WebSocket ) SendText (v string ) (err error ) {
133
149
defer handleJSError (& err , nil )
134
150
c .v .Call ("send" , v )
135
151
return err
136
152
}
137
153
138
- func (c * WebSocket ) SendBytes (v []byte ) (err error ) {
154
+ // SendBytes sends the given message as a binary message
155
+ // on the WebSocket.
156
+ func (c WebSocket ) SendBytes (v []byte ) (err error ) {
139
157
defer handleJSError (& err , nil )
140
158
c .v .Call ("send" , uint8Array (v ))
141
159
return err
0 commit comments