1

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

当我使用与 node.js websocket 交互的相同 JavaScript 客户端代码时,客户端会onclosews.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}.
4

1 回答 1

2

更新的答案:

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

{close, Status, Reason}

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

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

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

Yaws 永远不会将{close, Reason}消息传递给您的回调模块。相反,如果你的回调模块决定它想要关闭 ws 套接字,它{close, Reason}是一个有效的返回值。handle_message/1

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

所以,现在我相信你遇到了一个错误,即 Yaws websockets 支持没有检测到客户端关闭并关闭它的结束。我看看能不能修好。

于 2012-02-10T19:02:54.393 回答