当前位置: 首页 > 知识库问答 >
问题:

币安websocket没有响应ping

罗华翰
2023-03-14

我使用< code>gorilla/websocket拨打了币安websocketendpoint,成功无误。在连接上设置了pong处理程序后,我编写了一个ping控制消息,并等待pong到达pong处理程序,这似乎永远不会发生。我使用一个通道、一个超时上下文和一个< code>select块来检查pong是否到达。

代码:

package main

import (
    "context"
    "fmt"
    "log"
    "time"

    "github.com/gorilla/websocket"
)

func main() {
    ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
    defer cancel()

    conn, resp, err := websocket.DefaultDialer.DialContext(ctx, "wss://stream.binance.com:9443/ws", nil)
    if resp != nil {
        log.Printf("status: %s", resp.Status)
    }

    if err != nil {
        panic(err)
    }

    pong := make(chan struct{})
    conn.SetPongHandler(func(appData string) error {
        log.Println(appData)

        pong <- struct{}{}
        return nil
    })

    if err := conn.WriteControl(websocket.PingMessage, []byte("Hello, world!"), time.Now().Add(5*time.Second)); err != nil {
        panic(err)
    }

    select {
    case <-ctx.Done():
        panic(fmt.Errorf("pong wait: %w", ctx.Err()))
    case <-pong:
    }
}

输出:

$ go run ./cmd/ping
2022/02/07 20:01:23 status: 101 Switching Protocols
panic: pong wait: context deadline exceeded

goroutine 1 [running]:
main.main()
        /workspaces/yatgo/cmd/ping/ping.go:39 +0x2ba
exit status 2

根据rfc6455,第-5.5.2节:

5.5.2。平

ping帧包含0x9的操作码。

查验帧可以包括“应用数据”。

收到ping帧后,endpoint必须发送Pong帧作为响应,除非它已经收到了关闭帧。它应该在实际可行的情况下尽快使用Pong帧响应。Pong帧在第5.5.3节中讨论。

endpoint可以在连接建立之后和连接关闭之前的任何时间发送Ping帧。

注意:ping帧可以用作保持活动,也可以用作验证远程endpoint是否仍有响应的方法

我有点期待这能奏效。Binance webSocket API限制doc确实提到了ping消息:

WebSocket连接每秒最多有5条传入消息。消息被认为是:

    < Li > PING帧

所以我想知道:

  1. 我的代码有问题吗
  2. 还是二进制文件不尊重RFC6455

共有1个答案

西门鹏程
2023-03-14

大猩猩WebSocch留档说:

应用程序必须读取连接才能处理从对等方发送的关闭、ping 和 pong 消息。如果应用程序对来自对等方的消息不感兴趣,则应用程序应启动一个 goroutine 来读取和丢弃来自对等方的消息。

通过启动 goroutine 在 select 语句之前读取连接来修复应用程序:

go func() {
    defer cancel()
    for {
        if _, _, err := conn.NextReader(); err != nil {
            fmt.Println(err)
            return
        }
    }
}()

select {
⋮

这是对问题中显示的应用程序的修复。如果实际应用程序在循环中从连接读取数据,那么不应该添加此处显示的goroutine。应用程序应该使用一个读取循环来处理控制和数据消息。

 类似资料:
  • 问题内容: 我要做什么? 单击时,将执行。在方法内部,我将方法的每个索引传递给方法,以便可以在中显示它。 发生了什么 ? 如果我 不 守行作为 注释 ,在我的方法,则是 按预期工作 。尽管如果我将 其注释掉 ,则 停止响应 。 难道我做错了什么 ? Java版本: 这是我正在使用的代码: *编辑1:* 按照建议,如果我添加,它确实可以工作,但是会抛出如下所示的错误。这样就可以了。但这是 合法 的表

  • 昨天工作正常,一夜之间Windows7重新启动,现在Eclipse不会完成加载--旋转器显示“Eclipse SDK(未响应)”对话框“用户操作正在等待”完成“构建工作区”。Android SDK内容加载器保持在0%我尝试过: eclipse-clean delete c:\program files\eclipse\configuration.settings\org.eclipse.ui.id

  • 我用IntelliJ创建了一个非常简单的流测试。 IntelliJ无法完成测试,并给了我错误 这导致假设响应程序流不执行任何操作。 启动器流被执行。我可以看到这一点,因为命令显示在日志中。但是,我不知道响应器流是否从未由发起方流启动,或者只是没有响应。也许你可以帮我。 谢谢

  • 我在使用netty开发websocket服务器,浏览器使用var socket = new WebSocket("ws://127.0.0.1:18080/ws?token=xxxx");连接时服务器将验证token,如果不通过则返回401并关闭socket。 服务器响应代码: 目前情况是socket虽然关闭,但浏览器好像没有收到401的响应。我需要在浏览器种能知道连接关闭是因为401还是其他什么

  • 我是一个全新的计算机编程为CIS210和它的一个可怕的开始。下载了JDK9和Netbeans 8.2。Netbeans不允许我打开新项目或文件。没有错误消息或任何东西,几乎就像我没有点击它。屏幕保持空白,如下面的链接所示。快把我逼疯了。 单击“新建项目”时屏幕为空白:

  • 我要把我的代码移到服务器上。这段代码可以在我在localhost上设置的自己的服务器上完美地运行和呈现数据库信息,但是当我从服务器上运行代码时,index.html中会显示一个错误,说明“IO没有定义”。无论出于什么原因,socket.io都无法被识别。此外,如果我在浏览器中键入localhost:3000,则不会显示任何内容。任何帮助都将不胜感激。 我有两个文件,server.js和index.