@@ -50,6 +50,7 @@ type cap struct {
5050// much simpler.
5151type Client struct {
5252 * Conn
53+ rwc io.ReadWriteCloser
5354 config ClientConfig
5455
5556 // Internal state
@@ -63,9 +64,10 @@ type Client struct {
6364}
6465
6566// NewClient creates a client given an io stream and a client config.
66- func NewClient (rw io.ReadWriter , config ClientConfig ) * Client {
67+ func NewClient (rwc io.ReadWriteCloser , config ClientConfig ) * Client {
6768 c := & Client {
68- Conn : NewConn (rw ),
69+ Conn : NewConn (rwc ),
70+ rwc : rwc ,
6971 config : config ,
7072 errChan : make (chan error , 1 ),
7173 caps : make (map [string ]cap ),
@@ -238,25 +240,30 @@ func (c *Client) sendError(err error) {
238240 }
239241}
240242
241- func (c * Client ) startReadLoop (wg * sync.WaitGroup ) {
243+ func (c * Client ) startReadLoop (wg * sync.WaitGroup , exiting chan struct {} ) {
242244 wg .Add (1 )
243245
244246 go func () {
245247 defer wg .Done ()
246248
247249 for {
248- m , err := c .ReadMessage ()
249- if err != nil {
250- c .sendError (err )
251- break
252- }
250+ select {
251+ case <- exiting :
252+ return
253+ default :
254+ m , err := c .ReadMessage ()
255+ if err != nil {
256+ c .sendError (err )
257+ break
258+ }
253259
254- if f , ok := clientFilters [m .Command ]; ok {
255- f (c , m )
256- }
260+ if f , ok := clientFilters [m .Command ]; ok {
261+ f (c , m )
262+ }
257263
258- if c .config .Handler != nil {
259- c .config .Handler .Handle (c , m )
264+ if c .config .Handler != nil {
265+ c .config .Handler .Handle (c , m )
266+ }
260267 }
261268 }
262269
@@ -296,7 +303,7 @@ func (c *Client) RunContext(ctx context.Context) error {
296303
297304 // Now that the handshake is pretty much done, we can start listening for
298305 // messages.
299- c .startReadLoop (& wg )
306+ c .startReadLoop (& wg , exiting )
300307
301308 // Wait for an error from any goroutine or for the context to time out, then
302309 // signal we're exiting and wait for the goroutines to exit.
@@ -307,6 +314,7 @@ func (c *Client) RunContext(ctx context.Context) error {
307314 }
308315
309316 close (exiting )
317+ c .rwc .Close ()
310318 wg .Wait ()
311319
312320 return err
0 commit comments