我已经实现了一个简单的 appmod 来处理WebSockets并回显消息。但是如何从JavaScript客户端处理ws.close();
?我尝试使用下面的代码,但永远不会调用handle_message({close, Reason})
,并且永远不会在JavaScript客户端上执行ws.onclose = function(evt) {}
。
当我使用与node.js websocket交互的相同JavaScript客户端代码时,客户端会在onclose
之后立即收到ws.close();
个事件。
以下是我的简单 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}.
答案 0 :(得分:2)
更新回答:
从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我们建议只返回在所有情况下normal
的原子CloseReason
。
原始答案,由Yaws github提交16834c废弃:
Yaws永远不会将{close, Reason}
消息传递给您的回调模块。相反,如果您的回调模块决定要关闭ws套接字,{close, Reason}
是来自handle_message/1
的有效返回值。
我修改了Yaws(版本1.92)附带的websockets_example.yaws
文件,如果用户在网页上输入“bye”消息,则在客户端中调用this._ws.close()
,并向{添加警报{1}}函数显示触发了_onclose
事件。在这种情况下发生警报,我相信因为“再见”消息导致服务器显式关闭ws套接字。但是我随后修改了示例,无论用户输入什么消息,都在客户端中调用onclose
,在这种情况下,没有发生this._ws.close()
的警报。在这种情况下,使用onclose
的检查显示从浏览器到Yaws的ws连接仍然存在。
所以,现在我相信你已经遇到了一个错误,Yaws websockets支持没有检测到客户端关闭并关闭它的结束。我会看看能否解决它。