@@ -47,6 +47,7 @@ type Conn struct {
4747 // read limit for a message in bytes.
4848 msgReadLimit xsync.Int64
4949
50+ wg sync.WaitGroup
5051 closingMu sync.Mutex
5152 isReadClosed xsync.Int64
5253 closeOnce sync.Once
@@ -223,6 +224,7 @@ func (c *Conn) write(ctx context.Context, typ MessageType, p []byte) error {
223224// or the connection is closed.
224225// It thus performs the full WebSocket close handshake.
225226func (c * Conn ) Close (code StatusCode , reason string ) error {
227+ defer c .wg .Wait ()
226228 err := c .exportedClose (code , reason )
227229 if err != nil {
228230 return fmt .Errorf ("failed to close WebSocket: %w" , err )
@@ -236,6 +238,7 @@ func (c *Conn) Close(code StatusCode, reason string) error {
236238// note: No different from Close(StatusGoingAway, "") in WASM as there is no way to close
237239// a WebSocket without the close handshake.
238240func (c * Conn ) CloseNow () error {
241+ defer c .wg .Wait ()
239242 return c .Close (StatusGoingAway , "" )
240243}
241244
@@ -388,10 +391,15 @@ func (c *Conn) CloseRead(ctx context.Context) context.Context {
388391 c .isReadClosed .Store (1 )
389392
390393 ctx , cancel := context .WithCancel (ctx )
394+ c .wg .Add (1 )
391395 go func () {
396+ defer c .CloseNow ()
397+ defer c .wg .Done ()
392398 defer cancel ()
393- c .read (ctx )
394- c .Close (StatusPolicyViolation , "unexpected data message" )
399+ _ , _ , err := c .read (ctx )
400+ if err != nil {
401+ c .Close (StatusPolicyViolation , "unexpected data message" )
402+ }
395403 }()
396404 return ctx
397405}
0 commit comments