Im getting error: "concurrent write to websocket connection" when i try made a simple game server.
My server is here:
https://github.com/Shoen/phaser_multiplayer_demo/blob/master/server.go
After a lot of movement from the same player, if crashes in this line:
if err = p.Socket.WriteJSON(player.position(false)); err != nil {
Can anyone help me?
Connections do not support concurrent writers. Protect write with a mutex:
type Player struct {
Y int // Y position of the player
X int // X position
Id string // a unique id to identify the player by the frontend
Socket *websocket.Conn // websocket connection of the player
mu sync.Mutex
}
func (p *Player) send(v interface{}) error {
p.mu.Lock()
defer p.mu.Unlock()
return p.Socket.WriteJSON(v)
}
Replace all other p.Socket.WriteJSON(v) with calls with p.send(v).
I suggest running the application with the race detector. I suspect that there are other races.
Problem solved. There is any gorilla native way to do it? My code is the correct way?
There is any gorilla native way to do it?
I don't understand what you are asking. Can you please try to rephrase the question or add detail?
Ok.
I think that it is a common problem, concurrency. My question is about a gorilla implementation method that already have this mutex control, or everybody need do the same thing?
The server code that i show is the best method to make the server or have any best practices?
The application is responsible for ensuring that there's a single writer. A mutex is one way to do this. See the chat example for another approach.
See the Gorilla websocket examples for examples of how to write a server.
The code that you showed has a data race on Players and on the websocket connections.
type redisReceiver struct {
pool *redis.Pool
mu sync.Mutex
conns map[string]*websocket.Conn
}
func (rr *redisReceiver) broadcast(data []byte) {
rr.mu.Lock()
defer rr.mu.Unlock()
for id, conn := range rr.conns {
if err := conn.WriteMessage(websocket.TextMessage, data); err != nil {
fmt.Println("Error writting data to connection! Closing and removing Connection")
rr.deRegister(id)
}
}
}
This is my code. I am getting "concurrent write to websocket connection" in this part some times
What am I wrong?
@TianDaGe Is there code not shown here that writes to a connection?
nothing, that is all to write data via websocket connection. I am using Redis for broadcast.
I am using this sample
https://github.com/heroku-examples/go-websocket-chat-demo
My code is in the redis.go
@garyburd, I am waiting you :)
I do not have time to debug the application. Ask the author for help or search the application for all calls to WriteMessage and ensure that each call is protected by the mutex.
Most helpful comment
Connections do not support concurrent writers. Protect write with a mutex:
Replace all other
p.Socket.WriteJSON(v)with calls withp.send(v).I suggest running the application with the race detector. I suspect that there are other races.