Skip to content

Commit cf7313e

Browse files
committed
SCExample: Add option to use AsyncStreams in WebServerExample
1 parent f309a8f commit cf7313e

File tree

1 file changed

+50
-6
lines changed

1 file changed

+50
-6
lines changed

Examples/SCExample/Examples/WebServerExample/WebServerExample.cpp

Lines changed: 50 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,15 @@ struct SC::WebServerExampleModelState
3939
String interface = "127.0.0.1";
4040
int32_t port = 8090;
4141
int32_t maxClients = 32;
42+
bool useStreams = false;
4243
};
4344

4445
SC_REFLECT_STRUCT_VISIT(SC::WebServerExampleModelState)
4546
SC_REFLECT_STRUCT_FIELD(0, directory)
4647
SC_REFLECT_STRUCT_FIELD(1, interface)
4748
SC_REFLECT_STRUCT_FIELD(2, port)
4849
SC_REFLECT_STRUCT_FIELD(3, maxClients)
50+
SC_REFLECT_STRUCT_FIELD(4, useStreams)
4951
SC_REFLECT_STRUCT_LEAVE()
5052

5153
struct SC::WebServerExampleViewState
@@ -67,20 +69,55 @@ struct SC::WebServerExampleModel
6769
HttpAsyncServer httpServer;
6870
HttpWebServer httpWebServer;
6971

70-
Buffer headerBuffer;
72+
Buffer requestsMemory;
73+
Buffer headerBuffer;
74+
7175
GrowableBuffer<Buffer> gb = {headerBuffer};
7276
Span<HttpServerClient> clients;
7377

78+
Span<ReadableFileStream::Request> readRequests;
79+
Span<WritableFileStream::Request> writeRequests;
80+
81+
Span<AsyncBufferView> buffers;
82+
7483
Result start()
7584
{
85+
constexpr int REQUEST_SLICES = 2;
86+
constexpr int CLIENT_REQUEST = 1024;
87+
constexpr int HEADER_SIZE = 1024 * 8;
88+
7689
const size_t numClients = static_cast<size_t>(modelState.maxClients);
7790

78-
clients = {new HttpServerClient[numClients], numClients};
79-
SC_TRY(gb.resizeWithoutInitializing(1024 * 8 * numClients));
91+
SC_TRY(requestsMemory.resize(numClients * CLIENT_REQUEST));
92+
93+
// TODO: Simplify this messy manual memory handling
94+
clients = {new HttpServerClient[numClients], numClients};
95+
readRequests = {new ReadableFileStream::Request[numClients * REQUEST_SLICES], numClients* REQUEST_SLICES};
96+
writeRequests = {new WritableFileStream::Request[numClients * REQUEST_SLICES], numClients* REQUEST_SLICES};
97+
buffers = {new AsyncBufferView[numClients * (REQUEST_SLICES + 1)], numClients*(REQUEST_SLICES + 1)};
98+
99+
Span<char> requestsSpan = requestsMemory.toSpan();
100+
for (size_t idx = 0; idx < numClients; ++idx)
101+
{
102+
for (size_t slice = 0; slice < REQUEST_SLICES; ++slice)
103+
{
104+
Span<char> memory;
105+
const size_t offset = idx * CLIENT_REQUEST + slice * CLIENT_REQUEST / REQUEST_SLICES;
106+
(void)requestsSpan.sliceStartLength(offset, CLIENT_REQUEST / REQUEST_SLICES, memory);
107+
buffers[idx * REQUEST_SLICES + slice] = memory;
108+
}
109+
}
110+
111+
SC_TRY(gb.resizeWithoutInitializing(HEADER_SIZE * numClients));
80112
HttpServer::Memory memory = {gb, clients};
81113
httpServer.httpServer.onRequest.bind<HttpWebServer, &HttpWebServer::serveFile>(httpWebServer);
82-
SC_TRY(
83-
httpServer.start(*eventLoop, modelState.interface.view(), static_cast<uint16_t>(modelState.port), memory));
114+
if (modelState.useStreams)
115+
{
116+
httpServer.setUseAsyncStreams(true, readRequests, writeRequests, buffers);
117+
}
118+
119+
const uint16_t port = static_cast<uint16_t>(modelState.port);
120+
SC_TRY(httpServer.start(*eventLoop, modelState.interface.view(), port, memory));
84121
SC_TRY(httpWebServer.init(modelState.directory.view()));
85122
return Result(true);
86123
}
@@ -90,7 +127,13 @@ struct SC::WebServerExampleModel
90127
SC_TRY(httpWebServer.stopAsync());
91128
SC_TRY(httpServer.stopSync());
92129
delete[] clients.data();
93-
clients = {};
130+
delete[] readRequests.data();
131+
delete[] writeRequests.data();
132+
delete[] buffers.data();
133+
clients = {};
134+
readRequests = {};
135+
writeRequests = {};
136+
buffers = {};
94137
return Result(true);
95138
}
96139

@@ -133,6 +176,7 @@ struct SC::WebServerExampleView
133176
SC_TRY(InputText("Interface", buffer, model.modelState.interface, viewState.needsRestart));
134177
SC_TRY(InputText("Directory", buffer, model.modelState.directory, viewState.needsRestart));
135178
viewState.needsRestart |= ImGui::InputInt("Port", &model.modelState.port);
179+
viewState.needsRestart |= ImGui::Checkbox("Use Async Streams", &model.modelState.useStreams);
136180

137181
if (not model.httpServer.isStarted())
138182
{

0 commit comments

Comments
 (0)