Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 14 additions & 9 deletions core/network/WebSocket-wasm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
****************************************************************************/

#include "network/WebSocket-wasm.h"
#include "yasio/errc.hpp"
#include "base/Logging.h"

namespace ax
Expand Down Expand Up @@ -58,7 +57,7 @@ EM_BOOL WebSocket::em_ws_onclose(int eventType, const EmscriptenWebSocketCloseEv
if (!ws || !ws->_delegate)
return EM_TRUE;
ws->_state = WebSocket::State::CLOSED;
ws->_delegate->onClose(ws);
ws->_delegate->onClose(ws, (uint16_t)websocketEvent->code, websocketEvent->reason);
return EM_TRUE;
}

Expand All @@ -77,7 +76,13 @@ EM_BOOL WebSocket::em_ws_onmessage(int eventType, const EmscriptenWebSocketMessa

WebSocket::WebSocket() {}

WebSocket::~WebSocket() {}
WebSocket::~WebSocket()
{
if (_wsfd >= 0)
{
emscripten_websocket_delete(_wsfd);
}
}

bool WebSocket::open(Delegate* delegate, std::string_view url, std::string_view caFilePath, std::string_view protocols)
{
Expand All @@ -95,7 +100,7 @@ bool WebSocket::open(Delegate* delegate, std::string_view url, std::string_view
EmscriptenWebSocketCreateAttributes ws_attrs = {_url.c_str(),
_subProtocols.empty() ? nullptr : _subProtocols.c_str(), EM_TRUE};

AXLOGD("ws open url: {}, protocols: {}", ws_attrs.url, ws_attrs.protocols);
AXLOGD("ws open url: {}, protocols: {}", ws_attrs.url, ws_attrs.protocols ? ws_attrs.protocols : "");

_state = WebSocket::State::CONNECTING;
_wsfd = emscripten_websocket_new(&ws_attrs);
Expand All @@ -120,7 +125,7 @@ void WebSocket::send(std::string_view message)
{
auto error = emscripten_websocket_send_utf8_text(_wsfd, message.data());
if (error)
AXLOGW("Failed to emscripten_websocket_send_binary(): {}", error);
AXLOGW("Failed to emscripten_websocket_send_utf8_text(): {}", error);
}

/**
Expand All @@ -141,9 +146,9 @@ void WebSocket::send(const void* data, unsigned int len)
* @brief Closes the connection to server synchronously.
* @note It's a synchronous method, it will not return until websocket thread exits.
*/
void WebSocket::close()
void WebSocket::close(uint16_t code, std::string_view reason)
{
closeAsync(); // TODO
closeAsync(code, reason);
}

/**
Expand All @@ -152,12 +157,12 @@ void WebSocket::close()
* If using 'closeAsync' to close websocket connection,
* be careful of not using destructed variables in the callback of 'onClose'.
*/
void WebSocket::closeAsync()
void WebSocket::closeAsync(uint16_t code, std::string_view reason)
{
// close code: Uncaught DOMException: Failed to execute 'close' on 'WebSocket':
// The code must be either 1000, or between 3000 and 4999. 1024 is neither.
EMSCRIPTEN_RESULT error =
emscripten_websocket_close(_wsfd, 3000 - yasio::errc::shutdown_by_localhost, "shutdown by localhost");
emscripten_websocket_close(_wsfd, (unsigned short)code, reason.data());
if (!error)
_state = WebSocket::State::CLOSING;
else
Expand Down
6 changes: 3 additions & 3 deletions core/network/WebSocket-wasm.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ class AX_DLL WebSocket
*
* @param ws The WebSocket object connected.
*/
virtual void onClose(WebSocket* ws) = 0;
virtual void onClose(WebSocket* ws, uint16_t code, std::string_view reason) = 0;
/**
* This function is to be called in the following cases:
* 1. client connection is failed.
Expand Down Expand Up @@ -175,15 +175,15 @@ class AX_DLL WebSocket
* @brief Closes the connection to server synchronously.
* @note It's a synchronous method, it will not return until websocket thread exits.
*/
void close();
void close(uint16_t code = 1000, std::string_view reason = "Normal close");

/**
* @brief Closes the connection to server asynchronously.
* @note It's an asynchronous method, it just notifies websocket thread to exit and returns directly,
* If using 'closeAsync' to close websocket connection,
* be careful of not using destructed variables in the callback of 'onClose'.
*/
void closeAsync();
void closeAsync(uint16_t code = 1000, std::string_view reason = "Normal close");

/**
* @brief Gets current state of connection.
Expand Down
45 changes: 37 additions & 8 deletions core/network/WebSocket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -232,11 +232,13 @@ bool WebSocket::open(Delegate* delegate,
std::string_view caFilePath,
std::string_view protocols)
{
_delegate = delegate;
_url = url;
_caFilePath = FileUtils::getInstance()->fullPathForFilename(caFilePath);
_requestUri = Uri::parse(url);
_protocols = protocols;
_delegate = delegate;
_url = url;
_caFilePath = FileUtils::getInstance()->fullPathForFilename(caFilePath);
_requestUri = Uri::parse(url);
_protocols = protocols;
_closeCode = ws::detail::close_code::none;
_closeReason = "";

setupParsers();
generateHandshakeSecKey();
Expand Down Expand Up @@ -283,7 +285,7 @@ void WebSocket::dispatchEvents()
_delegate->onOpen(this);
break;
case Event::Type::ON_CLOSE:
_delegate->onClose(this);
_delegate->onClose(this, _closeCode, _closeReason);
break;
case Event::Type::ON_ERROR:
_delegate->onError(this, static_cast<ErrorEvent*>(event)->getErrorCode());
Expand Down Expand Up @@ -388,6 +390,14 @@ int WebSocket::on_frame_end(websocket_parser* parser)
break;
case WS_OP_CLOSE:
AXLOGD("WS: control frame: CLOSE");
if (ws->_receivedData.size() > 1)
{
if(ws->_closeCode == 0)
ws->_closeCode = ((uint16_t) ws->_receivedData.data()[0]) << 8 | ws->_receivedData.data()[1];

if (ws->_receivedData.size() > 2 && ws->_closeReason.empty())
ws->_closeReason = std::string(ws->_receivedData.data()[3], ws->_receivedData.size() - 2);
}
break;
case WS_OP_PING:
AXLOGD("WS: control frame: PING");
Expand Down Expand Up @@ -436,13 +446,27 @@ void WebSocket::send(const void* data, unsigned int len)
* @brief Closes the connection to server synchronously.
* @note It's a synchronous method, it will not return until websocket thread exits.
*/
void WebSocket::close()
void WebSocket::close(uint16_t code, std::string_view reason)
{
if (_state < State::CLOSING)
{
_closeCode = code;
_closeReason = reason;

if (_service->is_open(0))
{
_state = State::CLOSING;

std::vector<char> closeData(sizeof(_closeCode)+reason.size());
memcpy(closeData.data(), &_closeCode, sizeof(_closeCode));

if (!reason.empty())
{
memcpy(closeData.data()+sizeof(_closeCode), reason.data(), reason.size());
}

WebSocketProtocol::sendFrame(*this, closeData.data(), closeData.size(), ws::detail::opcode::close);

_service->close(0);

if (_transport)
Expand Down Expand Up @@ -470,7 +494,7 @@ void WebSocket::close()
* If using 'closeAsync' to close websocket connection,
* be careful of not using destructed variables in the callback of 'onClose'.
*/
void WebSocket::closeAsync()
void WebSocket::closeAsync(uint16_t code, std::string_view reason)
{
if (_state < State::CLOSING)
{
Expand Down Expand Up @@ -633,6 +657,11 @@ void WebSocket::handleNetworkEvent(yasio::io_event* event)
break;
case YEK_ON_CLOSE:
_transport = nullptr;
if(_closeCode == ws::detail::close_code::none)
{
_closeCode = ws::detail::close_code::abnormal;
_closeReason = "Abnormal close";
}
if (_state == State::OPEN || _state == State::CLOSING)
{
_state = State::CLOSED;
Expand Down
10 changes: 7 additions & 3 deletions core/network/WebSocket.h
Original file line number Diff line number Diff line change
Expand Up @@ -220,8 +220,10 @@ class AX_DLL WebSocket
* _readyState is State::CLOSING,this function is to be called.
*
* @param ws The WebSocket object connected.
* @param code the close code.
* @param reason the close reason.
*/
virtual void onClose(WebSocket* ws) = 0;
virtual void onClose(WebSocket* ws, uint16_t code, std::string_view reason) = 0;
/**
* This function is to be called in the following cases:
* 1. client connection is failed.
Expand Down Expand Up @@ -273,15 +275,15 @@ class AX_DLL WebSocket
* @brief Closes the connection to server synchronously.
* @note It's a synchronous method, it will not return until websocket thread exits.
*/
void close();
void close(uint16_t code = 1000, std::string_view reason = "Normal close");

/**
* @brief Closes the connection to server asynchronously.
* @note It's an asynchronous method, it just notifies websocket thread to exit and returns directly,
* If using 'closeAsync' to close websocket connection,
* be careful of not using destructed variables in the callback of 'onClose'.
*/
void closeAsync();
void closeAsync(uint16_t code = 1000, std::string_view reason = "Normal close");

/**
* @brief Gets current state of connection.
Expand Down Expand Up @@ -423,6 +425,8 @@ class AX_DLL WebSocket
/// the http status code returned from server, e.g. 200, 404, refer to
/// https://developer.mozilla.org/en-US/docs/Web/HTTP/Status
int _responseCode = -1;
uint16_t _closeCode;
std::string _closeReason;

// for receiveData
yasio::sbyte_buffer _receivedData;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ void LuaWebSocket::onMessage(WebSocket* ws, const WebSocket::Data& data)
}
}

void LuaWebSocket::onClose(WebSocket* ws)
void LuaWebSocket::onClose(WebSocket* ws, uint16_t code, std::string_view reason)
{
LuaWebSocket* luaWs = dynamic_cast<LuaWebSocket*>(ws);
if (NULL != luaWs) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class LuaWebSocket: public ax::network::WebSocket, public ax::network::WebSocket
~LuaWebSocket() override;;
void onOpen(WebSocket* ws) override;
void onMessage(WebSocket* ws, const WebSocket::Data& data) override;
void onClose(WebSocket* ws) override;
void onClose(WebSocket* ws, uint16_t code, std::string_view reason) override;
void onError(WebSocket* ws, const WebSocket::ErrorCode& error) override;

enum WebSocketScriptHandlerType
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ void WebSocketTest::onMessage(network::WebSocket* ws, const network::WebSocket::
}
}

void WebSocketTest::onClose(network::WebSocket* ws)
void WebSocketTest::onClose(network::WebSocket* ws, uint16_t code, std::string_view reason)
{
AXLOGD("onClose: websocket instance ({}) closed.", fmt::ptr(ws));
if (ws == _wsiSendText)
Expand Down Expand Up @@ -402,7 +402,7 @@ void WebSocketCloseTest::onMessage(network::WebSocket* ws, const network::WebSoc
AXLOGD("Websocket get message from {}", fmt::ptr(ws));
}

void WebSocketCloseTest::onClose(network::WebSocket* ws)
void WebSocketCloseTest::onClose(network::WebSocket* ws, uint16_t code, std::string_view reason)
{
AXLOGD("websocket ({}) closed.", fmt::ptr(ws));
// if (ws == _wsiTest) {
Expand Down Expand Up @@ -546,7 +546,7 @@ void WebSocketDelayTest::onMessage(network::WebSocket* ws, const network::WebSoc
}
}

void WebSocketDelayTest::onClose(network::WebSocket* ws)
void WebSocketDelayTest::onClose(network::WebSocket* ws, uint16_t code, std::string_view reason)
{
AXLOGD("onClose: websocket instance ({}) closed.", fmt::ptr(ws));
if (ws == _wsiSendText)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class WebSocketTest : public TestCase

virtual void onOpen(ax::network::WebSocket* ws)override;
virtual void onMessage(ax::network::WebSocket* ws, const ax::network::WebSocket::Data& data)override;
virtual void onClose(ax::network::WebSocket* ws)override;
virtual void onClose(ax::network::WebSocket* ws, uint16_t code, std::string_view reason)override;
virtual void onError(ax::network::WebSocket* ws, const ax::network::WebSocket::ErrorCode& error)override;

// Menu Callbacks
Expand Down Expand Up @@ -87,7 +87,7 @@ class WebSocketCloseTest : public TestCase

virtual void onOpen(ax::network::WebSocket* ws)override;
virtual void onMessage(ax::network::WebSocket* ws, const ax::network::WebSocket::Data& data)override;
virtual void onClose(ax::network::WebSocket* ws)override;
virtual void onClose(ax::network::WebSocket* ws, uint16_t code, std::string_view reason)override;
virtual void onError(ax::network::WebSocket* ws, const ax::network::WebSocket::ErrorCode& error)override;

WebSocketCloseTest();
Expand All @@ -113,7 +113,7 @@ class WebSocketDelayTest : public TestCase

virtual void onOpen(ax::network::WebSocket* ws)override;
virtual void onMessage(ax::network::WebSocket* ws, const ax::network::WebSocket::Data& data)override;
virtual void onClose(ax::network::WebSocket* ws)override;
virtual void onClose(ax::network::WebSocket* ws, uint16_t code, std::string_view reason)override;
virtual void onError(ax::network::WebSocket* ws, const ax::network::WebSocket::ErrorCode& error)override;

// Menu Callbacks
Expand Down