gorilla/websocket

[BUG] <title>panic: concurrent write to websocket connection

fanziyan opened this issue · 4 comments

Is there an existing issue for this?

  • I have searched the existing issues

Current Behavior

A mutex has been used when writing data, but it still prompts [panic: concurrent write to websocket connection]。
ws-panic

Expected Behavior

no panic happend

Steps To Reproduce

No response

Anything else?

#913

Hello @fanziyan

There were many issues like this in this repo. Usually it turns out that this panic helps to find concurrent write issues on early stages. And many issues were closed because users found the error in the app when they really concurrently writing to the WebSocket.

Having said that, please make sure it's the only usage of connection write in your app. Also, please provide a standalone reproducer if you made sure it's the only place and want the issue to be fixed. It's rather trivial to write the minimal reproducer and put some stress load on it to trigger the panic. But I guess you will find the mistake in your code while doing this.

This is probably because every time each goroutine calls the WriteMessage method, your mutex variable is copied, and the doc tells us that the mutex should not be copied after the first use. I had the same problem and I solved it by adding a mutex variable to the struct scope. In your case it might look like this

type GoViewConnection struct {
   viewWriteMutex sync.Mutex
   // other vars
}

func (c *GoViewConnection) WriteMessage(data []byte) error {
   c.viewWriteMutex.Lock()
   defer c.viewWriteMutex.Unlock()
   if c.Conn != nil {
      err := c.Conn.WriteMessage(messageType: 1, data)
      if err != nil {
         xwLog.LogByConfigAndLevel(model.ViewFuncModule+"WriteMessagetfl", logrus.InfoLevel)
         return err
      }
   }
   return nil
}

The code in the screenshot uses a named argument syntax that Go does not have.

Update the issue to show actual code.

Closing as #913 already touches this subject.