forked from Xeeynamo/sonic-hybrid-rsdk
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
173 additions
and
0 deletions.
There are no files selected for viewing
31 changes: 31 additions & 0 deletions
31
sonic3air-main/Oxygen/oxygenengine/source/oxygen_netcore/network/internal/SentPacketCache.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
/* | ||
* Part of the Oxygen Engine / Sonic 3 A.I.R. software distribution. | ||
* Copyright (C) 2017-2024 by Eukaryot | ||
* | ||
* Published under the GNU GPLv3 open source software license, see license.txt | ||
* or https://www.gnu.org/licenses/gpl-3.0.en.html | ||
*/ | ||
|
||
#pragma once | ||
|
||
#include "oxygen_netcore/network/internal/SentPacket.h" | ||
|
||
|
||
class SentPacketCache | ||
{ | ||
public: | ||
void clear(); | ||
uint32 getNextUniquePacketID() const; | ||
|
||
void addPacket(SentPacket& sentPacket, uint64 currentTimestamp, bool isStartConnectionPacket = false); | ||
|
||
void onPacketReceiveConfirmed(uint32 uniquePacketID); | ||
|
||
inline bool hasUnconfirmedPackets() const { return !mQueue.empty(); } | ||
void updateResend(std::vector<SentPacket*>& outPacketsToResend, uint64 currentTimestamp); | ||
|
||
private: | ||
uint32 mQueueStartUniquePacketID = 1; | ||
uint32 mNextUniquePacketID = 1; // This should always be "mQueueStartUniquePacketID + mQueue.size()" | ||
std::deque<SentPacket*> mQueue; // Can contain null pointers, anmely at the positions of packets that were already confirmed by the receiver | ||
}; |
142 changes: 142 additions & 0 deletions
142
...c3air-main/Oxygen/oxygenengine/source/oxygen_netcore/network/internal/WebSocketClient.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
/* | ||
* Part of the Oxygen Engine / Sonic 3 A.I.R. software distribution. | ||
* Copyright (C) 2017-2024 by Eukaryot | ||
* | ||
* Published under the GNU GPLv3 open source software license, see license.txt | ||
* or https://www.gnu.org/licenses/gpl-3.0.en.html | ||
*/ | ||
|
||
#include "oxygen_netcore/pch.h" | ||
#include "oxygen_netcore/network/internal/WebSocketClient.h" | ||
#include "oxygen_netcore/network/ConnectionManager.h" | ||
#include "oxygen_netcore/network/NetConnection.h" | ||
|
||
|
||
namespace | ||
{ | ||
//static const char* WEBSOCKET_PROTOCOL = "ws://"; // Only for testing | ||
static const char* WEBSOCKET_PROTOCOL = "wss://"; // This is required for the web build when running on a https website | ||
} | ||
|
||
|
||
WebSocketClient::WebSocketClient(NetConnection& connection) : | ||
mConnection(connection) | ||
{ | ||
} | ||
|
||
bool WebSocketClient::isAvailable() const | ||
{ | ||
// Web socket usage via emscripten is only available for the web version | ||
#ifdef PLATFORM_WEB | ||
return true; | ||
#else | ||
return false; | ||
#endif | ||
} | ||
|
||
void WebSocketClient::clear() | ||
{ | ||
#ifdef PLATFORM_WEB | ||
if (mWebSocket != 0) | ||
{ | ||
emscripten_websocket_close(mWebSocket, 1000, "Connection cleared"); | ||
emscripten_websocket_delete(mWebSocket); | ||
mWebSocket = 0; | ||
} | ||
#endif | ||
} | ||
|
||
bool WebSocketClient::connectTo(const SocketAddress& remoteAddress) | ||
{ | ||
#ifdef PLATFORM_WEB | ||
// Use web socket for communication (client-side only) | ||
if (!emscripten_websocket_is_supported()) | ||
return false; | ||
|
||
const std::string url = WEBSOCKET_PROTOCOL + remoteAddress.getIP() + ":" + std::to_string(remoteAddress.getPort()); | ||
EmscriptenWebSocketCreateAttributes attributes = | ||
{ | ||
url.c_str(), | ||
nullptr, | ||
EM_TRUE | ||
}; | ||
mWebSocket = emscripten_websocket_new(&attributes); | ||
if (mWebSocket == 0) | ||
return false; | ||
|
||
RMX_LOG_INFO("Successfully created web socket"); | ||
emscripten_websocket_set_onopen_callback (mWebSocket, this, WebSocketClient::webSocketOpenCallback); | ||
emscripten_websocket_set_onerror_callback (mWebSocket, this, WebSocketClient::webSocketErrorCallback); | ||
emscripten_websocket_set_onclose_callback (mWebSocket, this, WebSocketClient::webSocketCloseCallback); | ||
emscripten_websocket_set_onmessage_callback(mWebSocket, this, WebSocketClient::webSocketMessageCallback); | ||
return true; | ||
#else | ||
return false; | ||
#endif | ||
} | ||
|
||
bool WebSocketClient::sendPacket(const std::vector<uint8>& content) | ||
{ | ||
#ifdef PLATFORM_WEB | ||
if (mWebSocket == 0) | ||
return false; | ||
|
||
const EMSCRIPTEN_RESULT result = emscripten_websocket_send_binary(mWebSocket, (void*)&content[0], (uint32_t)content.size()); | ||
RMX_ASSERT(result == 0, "emscripten_websocket_send_binary failed with result " << result); | ||
return (result == 0); | ||
#else | ||
return false; | ||
#endif | ||
} | ||
|
||
|
||
#ifdef PLATFORM_WEB | ||
|
||
EM_BOOL WebSocketClient::webSocketOpenCallback(int eventType, const EmscriptenWebSocketOpenEvent* webSocketEvent, void* userData) | ||
{ | ||
return reinterpret_cast<WebSocketClient*>(userData)->onWebSocketOpen(webSocketEvent); | ||
} | ||
|
||
EM_BOOL WebSocketClient::webSocketErrorCallback(int eventType, const EmscriptenWebSocketErrorEvent* webSocketEvent, void* userData) | ||
{ | ||
return reinterpret_cast<WebSocketClient*>(userData)->onWebSocketError(webSocketEvent); | ||
} | ||
|
||
EM_BOOL WebSocketClient::webSocketCloseCallback(int eventType, const EmscriptenWebSocketCloseEvent* webSocketEvent, void* userData) | ||
{ | ||
// TODO: Implement this | ||
return EM_TRUE; | ||
} | ||
|
||
EM_BOOL WebSocketClient::webSocketMessageCallback(int eventType, const EmscriptenWebSocketMessageEvent* webSocketEvent, void* userData) | ||
{ | ||
return reinterpret_cast<WebSocketClient*>(userData)->onWebSocketMessage(webSocketEvent); | ||
} | ||
|
||
bool WebSocketClient::onWebSocketOpen(const EmscriptenWebSocketOpenEvent* webSocketEvent) | ||
{ | ||
RMX_LOG_INFO("onWebSocketOpen"); | ||
return mConnection.finishStartConnect(); | ||
} | ||
|
||
bool WebSocketClient::onWebSocketError(const EmscriptenWebSocketErrorEvent* webSocketEvent) | ||
{ | ||
RMX_LOG_INFO("onWebSocketError"); | ||
return true; | ||
} | ||
|
||
bool WebSocketClient::onWebSocketMessage(const EmscriptenWebSocketMessageEvent* webSocketEvent) | ||
{ | ||
RMX_LOG_INFO("onWebSocketMessage"); | ||
if (webSocketEvent->numBytes == 0) // Ignore empty messages | ||
return true; | ||
if (webSocketEvent->isText) // Only care for binary data | ||
return true; | ||
|
||
static std::vector<uint8> buffer; | ||
buffer.resize((size_t)webSocketEvent->numBytes); | ||
memcpy(&buffer[0], webSocketEvent->data, webSocketEvent->numBytes); | ||
return mConnection.receivedWebSocketPacket(buffer); | ||
} | ||
|
||
#endif |