HuobiRDCenter / huobi_Golang

Go SDK for Huobi Spot API
https://www.htx.com/zh-cn/opend/newApiPages/
Apache License 2.0
176 stars 86 forks source link

panic: concurrent write to websocket connection #7

Closed titilami closed 4 years ago

titilami commented 4 years ago

i subscribe websocket market data and receive realtime kline, Client.Subscribe("btcusdt", "1min", "2118"). i also obtain historical kline periodically by a time.ticker goroutine, Client.Request(xxxxxxx) but i got a panic finally after running a period of time,

panic: concurrent write to websocket connection

goroutine 33 [running]:
github.com/gorilla/websocket.(*messageWriter).flushFrame(0xc00007d260, 0xc000170001, 0x0, 0x0, 0x0, 0x7f01d726d108, 0x0)
        F:/go/pkg/mod/github.com/gorilla/websocket@v1.4.1/conn.go:610 +0x5e9
github.com/gorilla/websocket.(*messageWriter).Close(0xc00007d260, 0x0, 0xc0006c5de8)
        F:/go/pkg/mod/github.com/gorilla/websocket@v1.4.1/conn.go:724 +0x62
github.com/gorilla/websocket.(*Conn).beginMessage(0xc00054b4a0, 0xc000170030, 0x1, 0x0, 0xc0006c5e40)
        F:/go/pkg/mod/github.com/gorilla/websocket@v1.4.1/conn.go:473 +0x26d
github.com/gorilla/websocket.(*Conn).NextWriter(0xc00054b4a0, 0x1, 0x9, 0xbf6400, 0xc000328060, 0x20)
        F:/go/pkg/mod/github.com/gorilla/websocket@v1.4.1/conn.go:513 +0x53
github.com/gorilla/websocket.(*Conn).WriteMessage(0xc00054b4a0, 0x1, 0xc000328060, 0x17, 0x20, 0x20, 0x17)
        F:/go/pkg/mod/github.com/gorilla/websocket@v1.4.1/conn.go:766 +0x6e
github.com/huobirdcenter/huobi_golang/pkg/client/websocketclientbase.(*WebSocketClientBase).readLoop(0xc00006e360)
        F:/go/pkg/mod/github.com/huobirdcenter/huobi_golang@v0.0.0-20200420092918-b5239dd6398e/pkg/client/websocketclientbase/websocketclientbase.go:222 +0x528
created by github.com/huobirdcenter/huobi_golang/pkg/client/websocketclientbase.(*WebSocketClientBase).startReadLoop
        F:/go/pkg/mod/github.com/huobirdcenter/huobi_golang@v0.0.0-20200420092918-b5239dd6398e/pkg/client/websocketclientbase/websocketclientbase.go:174 +0x3f

i think the reason is time.Ticker goroutine and ping pong in "startReadLoop --> readLoop" write websocket simultaneous, how to solve it?

eynzhang commented 4 years ago

@titilami thanks for the feedback, I had a look the source code of websocket and I think we can find a solution. I will do more test and fix this.

titilami commented 4 years ago

@eynzhang thx, i have multi goroutines to send websocket request. These goroutines may call WebSocketClientBase.conn.WriteMessage simultaneous at sometime .

eynzhang commented 4 years ago

@titilami I think we need to handle it ourselves in SDK, the gorilla websocket doesn’t support concurrent write message, see below words from their documentation:

https://github.com/gorilla/websocket/blob/master/doc.go

Concurrency

Connections support one concurrent reader and one concurrent writer.

Applications are responsible for ensuring that no more than one goroutine
calls the write methods (NextWriter, SetWriteDeadline, WriteMessage,
WriteJSON, EnableWriteCompression, SetCompressionLevel) concurrently and
that no more than one goroutine calls the read methods (NextReader,
SetReadDeadline, ReadMessage, ReadJSON, SetPongHandler, SetPingHandler)
concurrently.

The Close and WriteControl methods can be called concurrently with all other
methods.
eynzhang commented 4 years ago

@titilami please get the lates update from master branch, the mutex is introduced to support concurrently subscribing. I tested it and it works well. You can refer to the new added traderexample.

titilami commented 4 years ago

@eynzhang thx.