2012-02-10 128 views
1

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

当我使用相同的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}. 

回答

2

更新答案:

由于github上的承诺16834c,最终将雅司病1.93的一部分,雅司病通过新的回调当客户端发送一个close消息时,您的WebSockets回调模块。回调:

{close, Status, Reason} 

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

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

原来的答复,由雅司病github上废弃的承诺16834c:

雅司病从来没有传递一个{close, Reason}邮件到您的回调模块。相反,{close, Reason}是一个有效的返回值,从handle_message/1如果您的回调模块决定要关闭ws套接字。

我修改了websockets_example.yaws文件,雅司病(版本1.92)出厂如果用户进入网页上的“拜拜”的消息调用this._ws.close()在客户端,并增加了警惕_onclose功能表明onclose事件被触发。在这种情况下发生了警报,我相信因为“再见”消息导致服务器显式关闭ws套接字。但是,我修改了这个例子,无论用户输入什么信息,都要在客户端调用this._ws.close(),在这种情况下,没有发生onclose的警报。在这种情况下,lsof的检查显示从浏览器到Yaws的ws连接仍然存在。

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

+0

谢谢,这是内容丰富的。我使用我发布的客户端代码[如何使用Yaws处理appmod中的WebSocket消息?](http://stackoverflow.com/questions/9187809/how-to-handle-websocket-messages-in-an-appmod-使用雅司)我有一个按钮“断开”。 – Jonas 2012-02-10 19:14:17

+0

使用Chrome 17.0.963.46当调用ws.close()时,我没有看到任何从浏览器到Yaws的“close”消息。我也试过Chrome的16版本,并没有看到它。你使用的是什么浏览器? – 2012-02-10 19:57:05

+0

我使用Chrome 16.相同的客户端代码使用node.js服务器。 – Jonas 2012-02-10 20:13:43