如何处理Yaws中客户端关闭的WebSocket?

时间:2012-02-10 04:41:45

标签: erlang websocket yaws

我已经实现了一个简单的 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}.

1 个答案:

答案 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支持没有检测到客户端关闭并关闭它的结束。我会看看能否解决它。