如何在Yaws中处理来自客户端的WebSocket关闭



我实现了一个简单的appmod,它处理WebSockets并回显消息。但是,我如何处理来自JavaScript客户端的ws.close();呢?我尝试过下面的代码,但handle_message({close, Reason})从未被调用,ws.onclose = function(evt) {}也从未在JavaScript客户端上执行。

当我使用相同的JavaScript客户端代码与node.js websocket交互时,客户端会在ws.close();之后立即接收到onclose事件。

以下是我的简单appmod:的代码

-module(mywebsocket).
-export([handle_message/1]).
handle_message({text, Message}) ->
    {reply, {text, <<Message/binary>>}};
handle_message({close, Reason}) ->
    io:format("User closed websocket.~n", []),
    {close, normal}.

更新答案:

从github提交16834c(它最终将成为Yaws 1.93的一部分)开始,当客户端发送close消息时,Yaws会将一个新的回调传递给您的WebSockets回调模块。回调为:

{close, Status, Reason}

其中Status是客户端发送的关闭状态,或者是数值1000(由RFC 6455指定用于正常关闭)(如果客户端不包括状态值)。Reason是保存从客户端传递的任何可选原因字符串的二进制;如果客户端无理由发送,它将是一个空二进制文件。

close消息的回调处理程序必须返回{close, CloseReason},其中CloseReason是正常关闭的原子normal(这导致状态代码1000返回给客户端)或RFC 6455允许的另一个合法数字状态代码。注意,CloseReason与客户端传递的任何Reason值无关。从技术上讲,CloseReason也可以是任何其他Erlang术语,在这种情况下,Yaws返回状态1000并将该术语传递给erlang:exit/1以退出处理web套接字的Erlang进程,但基于RFC 6455,我们建议在所有情况下都简单地为CloseReason返回原子normal

原始答案,由Yaws github commit 16834c:废弃

Yaws从不向回调模块传递{close, Reason}消息。相反,如果回调模块决定关闭ws套接字,{close, Reason}handle_message/1的有效返回值。

我修改了Yaws(1.92版)附带的websockets_example.yaws文件,以便在用户在网页上输入"再见"消息时调用客户端中的this._ws.close(),并向_onclose函数添加了一个警报,以显示onclose事件已触发。在这种情况下,我相信发生警报是因为"再见"消息导致服务器显式关闭ws套接字。但我随后修改了该示例,使其在客户端中调用this._ws.close(),无论用户输入什么消息,在这种情况下都不会出现onclose的警报。在这种情况下,使用lsof进行的检查显示,从浏览器到Yaws的ws连接仍然存在。

所以,现在我相信你遇到了一个错误,Yaws websockets支持没有检测到客户端关闭并关闭其端部。我会看看是否可以修复它。

相关内容

  • 没有找到相关文章

最新更新