1 回答

TA貢獻1802條經(jīng)驗 獲得超4個贊
總結(jié)我的評論作為答案:
當(dāng)您寫入客戶端時,您從 GlassFish 消息中獲取 clientId,從地圖中獲取客戶端,然后寫入它 - 基本上是clients[clientId].WriteMessage(...)。
雖然您的地圖訪問可以是線程安全的,但寫入不是,因為這可以被視為:
// map access - can be safe if you're using a concurrent map
client := clients[clientId]
// writing to a client, not protected at all
client.WriteMessage(...)
所以可能發(fā)生的事情是兩個單獨的 goroutine 同時寫入同一個客戶端。您應(yīng)該通過在WriteMessage方法實現(xiàn)中添加互斥鎖來保護您的客戶端免受它的影響。
順便說一句,實際上不是使用互斥鎖來保護此方法,而是使用一個通道來編寫消息,并且每個客戶端使用一個 goroutine 從通道中消費并寫入實際套接字,而不是使用互斥鎖來保護此方法。
所以在客戶端結(jié)構(gòu)中我會做這樣的事情:
type message struct {
msgtype string
msg string
}
type client struct {
...
msgqueue chan *message
}
func (c *client)WriteMessage(messageType, messageText string) {
// I'm simplifying here, but you get the idea
c.msgqueue <- &message{msgtype: messageType, msg: messageText}
}
func (c *client)writeLoop() {
go func() {
for msg := ragne c.msgqueue {
c.actuallyWriteMessage(msg)
}
}()
}
并且在創(chuàng)建新的客戶端實例時,只需啟動寫入循環(huán)
- 1 回答
- 0 關(guān)注
- 419 瀏覽
添加回答
舉報