我实现了一个简单的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支持没有检测到客户端关闭并关闭其端部。我会看看是否可以修复它。