2012-02-10 60 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