diff --git a/reference/AsyncWebSocket/AsyncWebSocket.cpp b/reference/AsyncWebSocket/AsyncWebSocket.cpp new file mode 100644 index 000000000..766351687 --- /dev/null +++ b/reference/AsyncWebSocket/AsyncWebSocket.cpp @@ -0,0 +1,75 @@ +#include + +using namespace Upp; + +struct Worker { + WebSocket ws; + + void Do(); + + Worker(); +}; + +void Worker::Do() +{ + String s = ws.Receive(); + if(s.GetCount()) { + LOG("Received request " << s); + ws.SendText(AsString(sqrt(atof(s)))); + } +} + +Worker::Worker() +{ + ws.NonBlocking(); +} + +void ClientEmulation(); + +CONSOLE_APP_MAIN +{ + StdLogSetup(LOG_COUT|LOG_FILE); + + WebSocket::Trace(); + + TcpSocket server; + server.Timeout(0); + + if(!server.Listen(12321, 5, false, true)) { + LOG("Cannot open server socket for listening!"); + Exit(1); + } + + ClientEmulation(); + + Array worker; + + LOG("Starting to listen"); + for(;;) { + if(server.IsError()) { + LOG("Server error: " << server.GetErrorDesc()); + server.ClearError(); + } + SocketWaitEvent sel; + sel.Add(server, WAIT_READ); + for(auto& w : worker) + w.ws.AddTo(sel); + sel.Wait(1000); + LOG("Waiting ended at " << GetSysTime()); + for(int i = worker.GetCount() - 1; i >= 0; i--) + if(sel[i + 1]) { + LOG("Event at worker " << i); + Worker& w = worker[i]; + w.Do(); + if(w.ws.IsClosed() || w.ws.IsError()) { + worker.Remove(i); + LOG("WebSocket closed, current count: " << worker.GetCount()); + } + } + if(sel[0]) + if(!worker.Add().ws.NonBlocking().Accept(server)) + worker.Drop(); + else + LOG("WebSocket accepted, current count: " << worker.GetCount()); + } +} diff --git a/reference/AsyncWebSocket/AsyncWebSocket.upp b/reference/AsyncWebSocket/AsyncWebSocket.upp new file mode 100644 index 000000000..3f6822f7f --- /dev/null +++ b/reference/AsyncWebSocket/AsyncWebSocket.upp @@ -0,0 +1,12 @@ +description "Demonstrates asynchronous WebSocket server\377"; + +uses + Core; + +file + Client.cpp, + AsyncWebSocket.cpp; + +mainconfig + "" = ""; + diff --git a/reference/AsyncWebSocket/Client.cpp b/reference/AsyncWebSocket/Client.cpp new file mode 100644 index 000000000..56a004b14 --- /dev/null +++ b/reference/AsyncWebSocket/Client.cpp @@ -0,0 +1,47 @@ +#include + +using namespace Upp; + +// Clients are run in blocking mode + +void ClientEmulation() +{ + Thread::Start([] { + #if 0 // change to 1 to dome single request + Sleep(500); + WebSocket ws; + ws.Connect("ws://127.0.0.1:12321"); + if(ws.IsError()) { + LOG("Failed to connect"); + return; + } + LOG("Client Request"); + ws.SendText(AsString(Random())); + LOG("Response: " << ws.Receive()); + ws.Close(); + #else + for(;;) { + Sleep(Random(2000)); + Thread::Start([] { + LOG("Started a new client"); + WebSocket ws; + ws.Connect("ws://127.0.0.1:12321"); + if(ws.IsError()) { + LOG("Failed to connect"); + return; + } + LOG("WebSocket connected to the server"); + while(Random(20) && ws.IsOpen()) { + String request = AsString(Random()); + LOG("Sending request " << request); + ws.SendText(request); + String reply = ws.Receive(); + LOG(request << " -> " << reply); + Sleep(Random(2000)); + } + ws.Close(); + }); + } + #endif + }); +} \ No newline at end of file diff --git a/reference/AsyncWebSocket/Client/Client.cpp b/reference/AsyncWebSocket/Client/Client.cpp new file mode 100644 index 000000000..90dc5208a --- /dev/null +++ b/reference/AsyncWebSocket/Client/Client.cpp @@ -0,0 +1,7 @@ +#include + +using namespace Upp; + +CONSOLE_APP_MAIN +{ +} diff --git a/reference/AsyncWebSocket/Client/Client.upp b/reference/AsyncWebSocket/Client/Client.upp new file mode 100644 index 000000000..cc78513d6 --- /dev/null +++ b/reference/AsyncWebSocket/Client/Client.upp @@ -0,0 +1,7 @@ +uses Core; + +file + Client.cpp; + +mainconfig + "" = "";