Documentation for the Unreal C++ Library
Loading...
Searching...
No Matches
MultiplayerWebSocket.cpp
Go to the documentation of this file.
1// Copyright(c) 2023 PixoVR, LLC. All Rights Reserved.
2
4#include "WebSocketsModule.h"
5
6DEFINE_LOG_CATEGORY_STATIC(LogMultiplayerWebSocket, Log, All);
7
8#define Log(pmt, ...) UE_LOG(LogMultiplayerWebSocket, Log, TEXT(pmt), ##__VA_ARGS__)
9#define Warn(pmt, ...) UE_LOG(LogMultiplayerWebSocket, Warning, TEXT(pmt), ##__VA_ARGS__)
10#define Error(pmt, ...) UE_LOG(LogMultiplayerWebSocket, Error, TEXT(pmt), ##__VA_ARGS__)
11#define Fatal(pmt, ...) UE_LOG(LogMultiplayerWebSocket, Fatal, TEXT(pmt), ##__VA_ARGS__)
12
14 bShouldRestartOnBadClose(true),
15 bShouldReplayLastRequestOnBadClose(true)
16{
17
18}
19
21{
22 Log("MultiplayerWebSocket destructor.");
23 Disconnect();
24}
25
27{
28 Log("MultiplayerWebSocket Disconnect.");
29 if (WebSocket.IsValid() && WebSocket->IsConnected())
30 {
31 Log("Disconnecting...");
32 // Clear the OnClosed event to prevent some access errors when the app is shutting down.
33 WebSocket->OnClosed().Clear();
34 WebSocket->OnConnected().Clear();
35 WebSocket->OnConnectionError().Clear();
36 WebSocket->Close();
37 }
38
39 WebSocket = nullptr;
40}
41
42bool MultiplayerWebSocket::AttemptConnect(FString Uri, FString Protocol)
43{
44 Log("Connecting to websocket at %s", *Uri);
45 if (WebSocket.IsValid() && WebSocket->IsConnected())
46 return false;
47
48 SocketUri = Uri;
49 SocketProtocol = Protocol;
50
52
53 if (!WebSocket.IsValid())
54 {
55 Log("Setting up the socket.");
56 SetupSocket(WebSocket, Uri, Protocol);
57 }
58
59 if (WebSocket)
60 {
61 Log("WebSocket connect called.");
62 WebSocket->Connect();
63 }
64 else
65 {
66 return false;
67 }
68
69 return true;
70}
71
73{
74 if (WebSocket.IsValid() && WebSocket->IsConnected())
75 return true;
76
77 return false;
78}
79
80void MultiplayerWebSocket::RequestMatchMake(int OrgId, int ModuleId)
81{
82 FString JsonString = FString::Format(TEXT("{ \"OrgId\": {0}, \"ModuleId\": {1}}"), { FStringFormatArg(OrgId), FStringFormatArg(ModuleId) });
84
85 if (WebSocket.IsValid() && WebSocket->IsConnected())
86 {
88 }
89}
90
91void MultiplayerWebSocket::SetupSocket(TSharedPtr<IWebSocket>& Socket, FString Uri, FString Protocol)
92{
93 if (!&FWebSocketsModule::Get())
94 {
95 return;
96 }
97
98 Socket = FWebSocketsModule::Get().CreateWebSocket(Uri, Protocol);
99
100 Socket->OnConnected().AddLambda([&]() -> void {
101 Log("WebSocket connected.");
103 SocketConnectedEvent.Broadcast();
104 });
105
106 Socket->OnConnectionError().AddLambda([&](const FString& Error) -> void {
107 Error("Failed to connect with error: %s", *Error);
110 });
111
112 Socket->OnClosed().AddLambda([&](int32 StatusCode, const FString& Reason, bool bWasClean) -> void {
113 Log("Socket closed with status %d, for reason %s", StatusCode, *Reason);
115 SocketDisconnectedEvent.Broadcast(StatusCode, Reason, bWasClean);
116 // Bad close caused by underlying WebSocket implementation. Only happens in the editor.
117 if (StatusCode == 1006 && bShouldRestartOnBadClose)
118 {
121 {
123 }
124 }
125 });
126
127 Socket->OnMessage().AddLambda([&](const FString& Message) -> void {
128 Log("Socket received message %s", *Message);
129 SocketMessageReceivedEvent.Broadcast(Message);
131 });
132
133 Socket->OnRawMessage().AddLambda([&](const void* Data, SIZE_T Size, SIZE_T BytesRemaining) -> void {
134 // This code will run when we receive a raw (binary) message from the server.
135 Log("A raw message was received of size %d.", Size);
136 });
137
138 Socket->OnMessageSent().AddLambda([&](const FString& MessageString) -> void {
139 Log("Apex message sent.");
141 });
142}
143
145{
146 if (PendingWebsocketRequests.Num() > 0)
147 {
148 auto NextRequest = PendingWebsocketRequests.Pop();
149
150 switch (NextRequest.RequestType)
151 {
153 {
154 SendData(NextRequest.Json);
155 }
156 break;
157 default:
158 Error("Invalid request type submitted of type %d", NextRequest.RequestType);
159 }
160
161 LastWebSocketRequest = NextRequest;
162 }
163}
164
169
171{
172 if (!WebSocket->IsConnected())
173 {
174 return;
175 }
176
177 WebSocket->Send(Data);
178}
179
180#undef Fatal
181#undef Error
182#undef Warn
183#undef Log
#define Error(pmt,...)
#define Log(pmt,...)
DEFINE_LOG_CATEGORY_STATIC(LogMultiplayerWebSocket, Log, All)
#define Log(pmt,...)
MultiplayerRequestData LastWebSocketRequest
FSocketDisconnected SocketDisconnectedEvent
TSharedPtr< IWebSocket > WebSocket
FSocketConnected SocketConnectedEvent
FSocketConnectFailed SocketConnectFailedEvent
void SetupSocket(TSharedPtr< IWebSocket > &Socket, FString Uri, FString Protocol)
TArray< MultiplayerRequestData > PendingWebsocketRequests
FSocketMessageReceived SocketMessageReceivedEvent
void RequestMatchMake(int OrgId, int ModuleId)
bool AttemptConnect(FString Uri, FString Protocol="wss")