Closed yzddd closed 4 months ago
Hey, which version do you use?
Hey, which version do you use?
Hi!. It is gobwas/ws v1.3.0
github.com/gobwas/ws v1.3.0
github.com/gobwas/httphead v0.1.0 // indirect
github.com/gobwas/pool v0.2.1 // indirect
Looks like the connection is closed on Binance side due to error in the payload, see message:
Received message: {"id":"1714803365000","status":400,"error":{"code":-1000,"msg":"Missing required 'method' in JSON request."}}
Looks like the connection is closed on Binance side due to error in the payload, see message:
Received message: {"id":"1714803365000","status":400,"error":{"code":-1000,"msg":"Missing required 'method' in JSON request."}}
Hi! Mr. Kovalov, I think I sent only one "ping" request and received a correct 200 response, as expected. However, I later received a 400 response indicating that the method was missing. I was confused.
I actually used gobwas‘ ”dialer.Dial“ function to connect to this address and establish a WebSocket connection. However, as soon as the connection is established, it gets disconnected, and I keep receiving EOF. This issue only occurs with this specific address; other addresses work fine. The original codebase is quite extensive, with many layers of abstraction. I spent an entire day troubleshooting but couldn't pinpoint the problem.
To validate, I tried using gorilla/websocket as a comparison, and I didn't encounter a similar issue. That's why I created this simple test code in the issue to see if I can reproduce this bug.
Check the 2nd if
in 1st goroutine. You send back what you've received from Binance:
{"id":"1714824103000","status":200,"result":{},"rateLimits":[{"rateLimitType":"REQUEST_WEIGHT","interval":"MINUTE","intervalNum":1,"limit":2400,"count":12}]}
In this payload there is no requested field 'method' as Binance says. Do you've a gorilla/websocket
reproducer that does exactly the same steps and receive something else in a response?
Do you've a
gorilla/websocket
reproducer that does exactly the same steps and receive something else in a response?
Hi, Yes, I tried the same code on Gorilla/WebSocket, and it seems to be working fine. Code
func TestGorillaWs(t *testing.T) {
interrupt := make(chan os.Signal, 1)
signal.Notify(interrupt, syscall.SIGINT, syscall.SIGTERM)
// WebSocket地址
//url := "wss://stream.binance.com:9443/ws/btcusdt@depth"
url := "wss://ws-fapi.binance.com/ws-fapi/v1"
// 连接到WebSocket地址
c, _, err := websocket.DefaultDialer.Dial(url, nil)
if err != nil {
log.Fatal("dial:", err)
}
defer c.Close()
done := make(chan struct{})
go func() {
defer close(done)
for {
_, message, err := c.ReadMessage()
if err != nil {
log.Println("read:", err)
return
}
fmt.Printf("Received: %s\n", message)
}
}()
go func() {
for {
ts := fmt.Sprintf("%d", time.Now().Unix()*1000)
pingMsg := map[string]interface{}{
"id": ts,
"method": "ping",
}
msg, err := json.Marshal(pingMsg)
if err != nil {
log.Println("json marshal error:", err)
return
}
err = c.WriteMessage(websocket.TextMessage, msg)
if err != nil {
log.Println("write ping message error:", err)
}
time.Sleep(5 * time.Second)
}
}()
select {}
}
output:
Running tool: /home/ubuntu/go/bin/go test -timeout 30s -run ^TestGorillaWs$
=== RUN TestGorillaWs
Received: {"id":"1714825512000","status":200,"result":{},"rateLimits":[{"rateLimitType":"REQUEST_WEIGHT","interval":"MINUTE","intervalNum":1,"limit":2400,"count":6}]}
Received: {"id":"1714825517000","status":200,"result":{},"rateLimits":[{"rateLimitType":"REQUEST_WEIGHT","interval":"MINUTE","intervalNum":1,"limit":2400,"count":7}]}
Received: {"id":"1714825522000","status":200,"result":{},"rateLimits":[{"rateLimitType":"REQUEST_WEIGHT","interval":"MINUTE","intervalNum":1,"limit":2400,"count":8}]}
Received: {"id":"1714825527000","status":200,"result":{},"rateLimits":[{"rateLimitType":"REQUEST_WEIGHT","interval":"MINUTE","intervalNum":1,"limit":2400,"count":9}]}
Received: {"id":"1714825532000","status":200,"result":{},"rateLimits":[{"rateLimitType":"REQUEST_WEIGHT","interval":"MINUTE","intervalNum":1,"limit":2400,"count":10}]}
Received: {"id":"1714825537000","status":200,"result":{},"rateLimits":[{"rateLimitType":"REQUEST_WEIGHT","interval":"MINUTE","intervalNum":1,"limit":2400,"count":11}]}
As mentioned above: You've an explicit send of received data:
if err := wsutil.WriteClientMessage(conn, op, msg); err != nil {
log.Printf("failed to write message: %v", err)
break
}
Tried to add similar code in gorilla/websocket
example and it will fail:
err = c.WriteMessage(websocket.TextMessage, message)
if err != nil {
log.Println("write ping message error:", err)
}
Oh! Thank you, this is indeed where the issue lies. Thanks for your kind help!
After establishing a WebSocket connection to an address, the connection is immediately dropped, and an EOF error is encountered. After multiple attempts, it seems that the reason may be that the client sends a certain request or handshake to the server, causing the client to disconnect on its own, triggering the 1008 error. Here is the code and output.I'm hoping for some assistance, your help would be greatly appreciated. Thank you!
Code:
OUTPUT: Running tool: /home/ubuntu/go/bin/go test -timeout 30s -run ^TestGobwasWs$ === RUN TestGobwasWs Received message: {"id":"1714779322000","status":200,"result":{},"rateLimits":[{"rateLimitType":"REQUEST_WEIGHT","interval":"MINUTE","intervalNum":1,"limit":2400,"count":6}]} Received message: {"id":"1714779322000","status":400,"error":{"code":-1000,"msg":"Missing required 'method' in JSON request."}} 2024/05/04 07:35:22 failed to read message: ws closed: 1008 disconnected 2024/05/04 07:35:27 failed to write message: write tcp 10.0.4.10:58838->18.182.135.180:443: write: broken pipe