Обновленный ответ:
Начиная с коммита 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 не определяет закрытие клиента и закрытие его конца. Я посмотрю, смогу ли я это исправить.