从浏览器发送websocket ping/pong框架

dan*_*nny 121 javascript websocket mongrel2

我一直在阅读websockets中的ping/pong消息以保持连接活着,但我不确定它们是什么.它是一种独特的框架类型吗?(我没有在与乒乓相关的chrome中的javascript WebSocket对象上看到任何方法).或者它只是一种设计模式(例如,我将"ping"或任何其他字符串发送到服务器并让它响应).乒乓球是否与延续帧有关?

我问的原因是我正在使用一个在Mongrel2后面运行的python框架,所以我想知道是否有办法向Mongrel2发送一条特定的ping/pong消息,告诉它在没有我的python应用需要的情况下保持连接存活担心它.我想,类似于有一个单独的HTTP方法.而且我认为专用的ping/pong消息帧可能比字符串"ping"更简单(服务器和网络上的负载更少),尽管这可能无关紧要.

编辑:我只看了RFC 6455,它看起来像Ping和Pong肯定是控制帧类型与自己的操作码.那么如何从Chrome中的javascript发送Ping帧?

kan*_*aka 110

没有Javascript API来发送ping帧或接收pong帧.这是您的浏览器支持或不支持.也没有API来启用,配置或检测浏览器是否支持并使用ping/pong帧.有关于为此创建Javascript ping/pong API的讨论.pings有可能在未来可配置/可检测,但Javascript不太可能直接发送和接收ping/pong帧.

但是,如果您同时控制客户端和服务器代码,则可以轻松地在更高级别添加ping/pong支持.如果您还没有,那么您的消息中将需要某种消息类型标题/元数据,但这非常简单.除非您计划每秒发送数百次ping或拥有数千个并发客户端,否则自己完成此操作的开销很小.

  • 这就是“ws”Websocket 库的做法:https://github.com/websockets/ws/blob/8a7016dc2fe4d9d63c428c67588d7c1f33a72e5c/lib/sender.js#L209 (3认同)
  • 是否可以以编程方式创建包含“ping”帧的二进制帧? (2认同)

mok*_*oka 23

Ping只能从服务器发送到客户端,浏览器应该尽快使用Pong OpCode自动回答.所以你不必担心更高层次的问题.

尽管并非所有浏览器都支持标准,但它们在实现此类机制时可能存在一些差异,甚至可能意味着没有Pong响应功能.但我个人正在使用Ping/Pong,从未看到客户端没有在低级客户端实现上实现这种类型的OpCode和自动响应.

  • 你在哪里读到ping只是从服务器到客户端?RFC说"端点可以在建立连接之后和连接关闭之前随时发送Ping帧." (62认同)
  • 在RFC 6455,WebSocket协议中,它明确指出:"注意:Ping帧可以用作keepalive,也可以用来验证远程端点是否仍然响应." (12认同)
  • 当没有收到RST/FIN数据包时,TCP不会通知断开连接.TCP仅在发件人尝试发送断开连接时检测到丢弃的连接.Ping在许多应用程序中用作心跳,它是有效的用途.在客户端尝试发送之前,死连接将永远保持不变.因此,对于浏览器上的WebSockets,必须使用自定义ping(或心跳)消息来检测客户端上的客户端断开连接.服务器可能正在尝试ping并检测到客户端断开连接,但未通知客户端.客户端ping也没关系. (11认同)
  • 如果您希望客户端自动检测断开状态(当没有收到RST/FIN数据包但网络已断开连接时),那么您还需要让客户端启动ping数据包. (5认同)
  • 当经常刷新用户代理时,建议使用仅限服务器的ping操作.但现在很多网站都被设计为SPA.在此环境中,客户端应用程序定期ping服务器以确保连接未丢失可能非常重要. (4认同)
  • Ping可以由客户端或服务器发送.https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_servers#Pings_and_Pongs_The_Heartbeat_of_WebSockets (3认同)
  • 客户端发送 KeepAlive PING 是很常见的,实际上许多 wss API 现在需要每 60 秒左右发送一次 PING,并在客户端不发起 PING 的情况下主动关闭连接。2012 年的“常识”不再适用,但是,您的声明始终与 RFC6455 的措辞相矛盾 https://tools.ietf.org/html/rfc6455#section-5.5.2 我建议您删除“Ping 只能从服务器发送到客户端”位。 (3认同)
  • 2021 年中期的世界还是这样吗?我们还没有就如何说“嘿,你还在吗?”达成一致。使用 WebSocket? (3认同)
  • 我从事服务器端和客户端 Websocket 开发已经一年多了,我发现 Javascript API 无法发送 ping 帧,这让我相当沮丧。如果能够 ping 我的服务器并使用 RTT 重新分配负载,那就太好了。这可以从服务器完成,但拥有客户端功能更有意义。我想不出客户端 ping 的实际缺点。 (2认同)
  • 因此,我仍然有些困惑...看来浏览器并没有做到这一点,也没有API。除了通过Websocket.prototype.send发送文本外,似乎没有其他方法可以发送任何内容,因此我无法操纵标题等。我非常接近实现自己的解决方案,即发送“ PING”并期望“ PONG”,但是我感觉到这不是应该怎么做的。我可以同时控制客户端和服务器。 (2认同)
  • 我们如何告诉JS开发人员我们需要API来配置乒乓间隔?我不想手动发送和接收乒乓消息,但是在后台必须实现此机制。而且我只需要API即可配置它。pingIntervals,超时。今天的2018年,真可惜。 (2认同)

xgq*_*rms 7

另一种 JavaScript 解决方案发送空数据帧,而不是 ping 帧:

如果 WebSocket 服务器主动ws在几分钟后断开链接,则服务器和客户端之间不会发送任何消息。

  1. 客户端主动发送自定义ping消息,通过使用该keepAlive函数保持活动状态

  2. 服务器端会忽略自定义ping消息并响应自定义pong消息

let timerId = 0; 

function keepAlive(timeout = 20000) { 
    if (webSocket.readyState == webSocket.OPEN) {  
        webSocket.send('');  
    }  
    timerId = setTimeout(keepAlive, timeout);  
}

function cancelKeepAlive() {  
    if (timerId) {  
        clearTimeout(timerId);  
    }  
}

Run Code Online (Sandbox Code Playgroud)

  • 此代码发送空帧,而不是 ping 或 pong 帧。 (5认同)