Как мне обработать закрытие WebSocket от клиента в Yaws? - PullRequest
1 голос
/ 10 февраля 2012

Я реализовал простой appmod , который обрабатывает WebSockets и выводит сообщения обратно.Но как мне обработать ws.close(); из клиента JavaScript?Я пробовал использовать приведенный ниже код, но handle_message({close, Reason}) никогда не вызывается и ws.onclose = function(evt) {} никогда не выполняется на клиенте JavaScript.

Когда я использую тот же код клиента JavaScript, взаимодействующий с веб-сокетом node.js,клиент получает событие 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 Ответ

2 голосов
/ 10 февраля 2012

Обновленный ответ:

Начиная с коммита github 16834c, который в конечном итоге станет частью Yaws 1.93, Yaws передает новый обратный вызов вашему модулю обратного вызова WebSockets, когда клиент отправляет сообщение close. Обратный вызов:

{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, чтобы выйти из процесса Erlang, обрабатывающего веб-сокет, но на основе RFC 6455 мы предлагаем просто вернуть атом normal для CloseReason во всех случаях.

Оригинальный ответ, устарел коммит Yaws github 16834c:

Yaws никогда не передает сообщение {close, Reason} в модуль обратного вызова. Скорее, {close, Reason} является допустимым возвращаемым значением из handle_message/1, если ваш модуль обратного вызова решит, что хочет закрыть сокет ws.

Я изменил файл websockets_example.yaws, поставляемый с Yaws (версия 1.92), чтобы он вызывал this._ws.close() в клиенте, если пользователь вводит сообщение "пока" на веб-странице, и добавил предупреждение для функции _onclose, чтобы показать, что событие onclose запущено. В этом случае предупреждение произошло, я полагаю, потому что сообщение "пока" заставляет сервер явно закрывать сокет ws. Но затем я изменил пример так, чтобы он вызывал this._ws.close() на клиенте, независимо от того, какое сообщение вводит пользователь, и в этом случае оповещение для onclose не происходило. В этом случае проверка с lsof показала, что соединение ws от браузера до Yaws все еще присутствует.

Итак, сейчас я считаю, что вы столкнулись с ошибкой, когда поддержка веб-сокетов Yaws не определяет закрытие клиента и закрытие его конца. Я посмотрю, смогу ли я это исправить.

...