@@ -25,16 +25,14 @@ THE SOFTWARE.
25
25
package gcd
26
26
27
27
import (
28
- "io "
28
+ "context "
29
29
"log"
30
- "net"
31
30
"sync"
32
31
"sync/atomic"
33
32
"time"
34
33
35
34
"github.com/wirepair/gcd/gcdapi"
36
35
"github.com/wirepair/gcd/gcdmessage"
37
- "golang.org/x/net/websocket"
38
36
)
39
37
40
38
// TargetInfo defines the 'tab' or target for this chrome instance,
@@ -57,13 +55,14 @@ type TargetInfo struct {
57
55
// Events are handled by mapping the method name to a function which takes a target and byte output.
58
56
// For now, callers will need to unmarshall the types themselves.
59
57
type ChromeTarget struct {
58
+ ctx context.Context
60
59
sendId int64 // An Id which is atomically incremented per request.
61
60
// must be at top because of alignement and atomic usage
62
61
replyLock sync.RWMutex // lock for dispatching responses
63
62
replyDispatcher map [int64 ]chan * gcdmessage.Message // Replies to synch methods using a non-buffered channel
64
63
eventLock sync.RWMutex // lock for dispatching events
65
64
eventDispatcher map [string ]func (* ChromeTarget , []byte ) // calls the function when events match the subscribed method
66
- conn * websocket. Conn // the connection to the chrome debugger service for this tab/process
65
+ conn * wsConn // the connection to the chrome debugger service for this tab/process
67
66
68
67
// Chrome Debugger Domains
69
68
Accessibility * gcdapi.Accessibility
@@ -122,8 +121,8 @@ type ChromeTarget struct {
122
121
}
123
122
124
123
// openChromeTarget creates a new Chrome Target by connecting to the service given the URL taken from initial connection.
125
- func openChromeTarget (addr string , target * TargetInfo ) (* ChromeTarget , error ) {
126
- conn , err := wsConnection (addr , target .WebSocketDebuggerUrl )
124
+ func openChromeTarget (ctx context. Context , addr string , target * TargetInfo ) (* ChromeTarget , error ) {
125
+ conn , err := wsConnection (ctx , target .WebSocketDebuggerUrl )
127
126
if err != nil {
128
127
return nil , err
129
128
}
@@ -135,6 +134,7 @@ func openChromeTarget(addr string, target *TargetInfo) (*ChromeTarget, error) {
135
134
doneCh := make (chan struct {})
136
135
chromeTarget := & ChromeTarget {conn : conn , Target : target , sendCh : sendCh , replyDispatcher : replier , eventDispatcher : eventer , doneCh : doneCh , sendId : 0 }
137
136
chromeTarget .apiTimeout = 120 * time .Second // default 120 seconds to wait for chrome to respond to us
137
+ chromeTarget .ctx = ctx
138
138
chromeTarget .Init ()
139
139
chromeTarget .listen ()
140
140
return chromeTarget , nil
@@ -262,9 +262,10 @@ func (c *ChromeTarget) listenWrite() {
262
262
c .replyLock .Unlock ()
263
263
264
264
c .debugf ("%d sending to chrome. %s\n " , msg .Id , msg .Data )
265
-
266
- err := websocket . Message . Send (c .conn , string ( msg .Data ) )
265
+ log . Printf ( "%d sending to chrome. %s \n " , msg . Id , msg . Data )
266
+ err := c . conn . Write (c .ctx , msg .Data )
267
267
if err != nil {
268
+ log .Printf ("error sending message: %s\n " , err )
268
269
c .debugf ("error sending message: %s\n " , err )
269
270
return
270
271
}
@@ -277,25 +278,42 @@ func (c *ChromeTarget) listenWrite() {
277
278
278
279
// Listens for responses coming in from the Chrome Debugger Service.
279
280
func (c * ChromeTarget ) listenRead () {
281
+ readCh := make (chan []byte , 1 )
282
+ writeClosed := make (chan struct {})
283
+ go func () {
284
+ for {
285
+ var msg []byte
286
+ err := c .conn .Read (c .ctx , & msg )
287
+ if err != nil {
288
+ c .debugf ("error in ws read: %s\n " , err )
289
+ close (writeClosed )
290
+ return
291
+ } else {
292
+ select {
293
+ case <- c .ctx .Done ():
294
+ return
295
+ case readCh <- msg :
296
+ }
297
+ }
298
+ }
299
+ }()
300
+
280
301
for {
281
302
select {
303
+ case <- writeClosed :
304
+ return
282
305
// receive done from listenWrite
283
306
case <- c .doneCh :
284
307
return
285
- // read data from websocket connection
286
- default :
287
- var msg string
288
- err := websocket .Message .Receive (c .conn , & msg )
289
- if err == io .EOF {
290
- c .debugf ("error io.EOF in websocket read" )
291
- return
292
- } else if err != nil {
293
- c .debugf ("error in ws read: %s\n " , err )
294
- } else {
295
- go c .dispatchResponse ([]byte (msg ))
308
+ case <- c .ctx .Done ():
309
+ return
310
+ case msg := <- readCh :
311
+ if len (msg ) != 0 {
312
+ c .dispatchResponse (msg )
296
313
}
297
314
}
298
315
}
316
+
299
317
}
300
318
301
319
type responseHeader struct {
@@ -374,20 +392,11 @@ func (c *ChromeTarget) checkTargetDisconnected(method string) {
374
392
}
375
393
376
394
// Connects to the tab/process for sending/recv'ing debug events
377
- func wsConnection (addr , url string ) (* websocket. Conn , error ) {
378
- conn , err := net . Dial ( "tcp" , addr )
395
+ func wsConnection (ctx context. Context , url string ) (* wsConn , error ) {
396
+ client , err := newWsConnDial ( ctx , url )
379
397
if err != nil {
380
398
return nil , err
381
399
}
382
-
383
- config , errConfig := websocket .NewConfig (url , "http://localhost" )
384
- if errConfig != nil {
385
- return nil , errConfig
386
- }
387
- client , errWS := websocket .NewClient (config , conn )
388
- if errWS != nil {
389
- return nil , errWS
390
- }
391
400
return client , nil
392
401
}
393
402
0 commit comments