I save my websockets in map using a uuid e.g.
sockets["123456"] = *websocket.Conn
and a function that passes a message to a channel
func (mr MessageRequest) Send(msg []byte) {
mr.mu.RLock()
defer mr.mu.RUnlock()
for _, socket := range mr.sockets {
mr.chat.broadcast <- Message{
socket: socket,
message: msg,
chat: mr.chat,
}
}
}
The channel that processes the message is as follows
case mr := <-c.broadcast:
msg := mr.message
if c.sockets[mr.socket] != nil {
if err := c.sockets[mr.socket].WriteMessage(websocket.TextMessage, msg); err != nil {
c.sockets[mr.socket].SetWriteDeadline(time.Now().Add(10 * time.Second))
c.sockets[mr.socket].WriteMessage(websocket.CloseMessage, []byte{})
c.sockets[mr.socket].Close()
go c.Unregister(c.sockets[mr.socket])
}
}
The problem comes from this line when there are many clients connected, and some clients disconnects quickly.
if err := c.sockets[mr.socket].WriteMessage(websocket.TextMessage, msg); err != nil
The error is
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x10 pc=0x139b430]
goroutine 138 [running]:
github.com/fasthttp/websocket.(*Conn).WriteMessage(0x164f3c0?, 0xc0002a57d0?, {0xc0000380e0, 0x70, 0x70})
/Users/username/go/pkg/mod/github.com/fasthttp/websocket@v1.5.0/conn.go:760 +0x30
I think it happens because sockets[“123456”] has been deleted when it Unregister. I already did a check using if c.sockets[mr.socket] != nil {
but my application still crash because of the line above.
I don’t know how to solve this scenario and I need help please.
PS: If it helps, my unregister function is like the following
case connection := <-c.unregister:
uuid := connection.uuid
if c.sockets[uuid] != nil { // avoid multiple deletion
c.mu.Lock()
delete(c.sockets, uuid)
c.mu.Unlock()
}