问题描述
我已经实现了一个简单的 appmod 来处理WebSockets并回传消息。但是如何从JavaScript客户端处理一个 ws.close();
?我尝试使用下面的代码,但是 handle_message({close,Reason})
从来没有被调用, ws.onclose = function(evt){}
从未在JavaScript客户端上执行。
I have implemented a simple appmod that handle WebSockets and echo back the messages. But how do I handle an ws.close();
from the JavaScript client? I have tried with the code below, but handle_message({close, Reason})
is never called and ws.onclose = function(evt) {}
is never executed on the JavaScript client.
当我使用与node.js websocket交互的相同JavaScript客户端代码时,客户端会收到 onclose
事件紧随 ws.close();
。
When I use the same JavaScript client code interacting with a node.js websocket, the client receives an onclose
event immediately after ws.close();
.
以下是我简单的 appmod 的代码:
Here is the code for my simple 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 commit 16834c,最终将成为Yaws 1.93的一部分,当客户端发送 close
消息。回调是:
As of github commit 16834c, which will eventually be part of Yaws 1.93, Yaws passes a new callback to your WebSockets callback module when the client sends a close
message. The callback is:
{close, Status, Reason}
其中状态
是客户端发送的关闭状态,或数值1000(由RFC 6455为正常关闭)如果客户端没有包括状态值。 原因
是一个二进制,包含从客户端传递的任何可选原因字符串;如果客户端没有发送任何理由,它将是一个空的二进制文件。
where Status
is either the close status sent by the client, or the numerical value 1000 (specified by RFC 6455 for a normal close) if the client didn't include a status value. Reason
is a binary holding any optional reason string passed from the client; it will be an empty binary if the client sent no reason.
close
消息的回调处理程序必须返回 {close,CloseReason}
其中 CloseReason
是原子正常
用于正常关闭(导致状态代码1000返回给客户端)或RFC 6455允许的另一个合法的数字状态代码。请注意, CloseReason
与任何客户端传递的原因
值。技术上 CloseReason
也可以是任何其他Erlang术语,在这种情况下,Yaws返回状态1000,并将术语传递到 erlang:exit / 1
退出处理Web套接字的Erlang进程,但是基于RFC 6455,我们建议简单地返回原子正常
CloseReason
在所有情况下。
Your callback handler for a close
message MUST return {close, CloseReason}
where CloseReason
is either the atom normal
for a normal close (which results in the status code 1000 being returned to the client) or another legal numerical status code allowed by RFC 6455. Note that CloseReason
is unrelated to any Reason
value passed by the client. Technically CloseReason
can also be any other Erlang term, in which case Yaws returns status 1000 and passes the term to erlang:exit/1
to exit the Erlang process handling the web socket, but based on RFC 6455 we suggest simply returning the atom normal
for CloseReason
in all cases.
原来的答案,由Yaws github提交16834c:
Original answer, obsoleted by Yaws github commit 16834c:
一个 {close,Reason}
消息给你的回调模块。相反, {close,Reason}
是从 handle_message / 1
的有效返回值,如果您的回调模块决定要关闭ws套接字。
Yaws never passes a {close, Reason}
message to your callback module. Rather, {close, Reason}
is a valid return value from handle_message/1
should your callback module decide it wants to close the ws socket.
我修改了Yaws(1.92版)附带的 websockets_example.yaws
文件,以调用 this._ws.close()
如果用户在网页上输入再见消息,并向 _onclose
函数来显示 onclose
事件被触发。在这种情况下,发生警报,我相信由于再见消息导致服务器明确关闭ws套接字。但是,我随后修改了该示例,在客户端中调用 this._ws.close()
,无论用户输入什么消息,在这种情况下,都不会对 onclose
发生。在这种情况下,使用 lsof
的检查显示从浏览器到Yaws的ws连接仍然存在。
I modified the websockets_example.yaws
file shipped with Yaws (version 1.92) to call this._ws.close()
in the client if the user enters the "bye" message on the web page, and added an alert to the _onclose
function to show that the onclose
event is triggered. In this case the alert occurred, I believe because the "bye" message causes the server to close the ws socket explicitly. But I then modified the example to call this._ws.close()
in the client no matter what message the user enters, and in that case no alert for onclose
occurred. In this case, a check with lsof
showed the ws connection from the browser to Yaws was still present.
所以现在我相信你已经遇到了Yaws websockets支持的错误,没有检测到客户端关闭并关闭其结束。我会看看是否可以解决它。
So, for now I believe you've hit a bug where the Yaws websockets support isn't detecting the client close and closing its end. I'll see if I can fix it.
这篇关于如何从雅虎的客户端处理WebSocket?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!