summaryrefslogtreecommitdiff
path: root/modules/io_codec/examples/echo_server.cpp
diff options
context:
space:
mode:
authorClaudius "keldu" Holeksa <mail@keldu.de>2024-05-14 14:14:58 +0200
committerClaudius "keldu" Holeksa <mail@keldu.de>2024-05-14 14:14:58 +0200
commit51dee3ca45265e905b65be85d078d20e68b4072b (patch)
treeea23f85789e1c50c8b209d968b9365cd25490ed7 /modules/io_codec/examples/echo_server.cpp
parent007ef1d1ae4fc9a1bea3dec3992ae13f6e054f36 (diff)
Echo example is not made by peer code
Diffstat (limited to 'modules/io_codec/examples/echo_server.cpp')
-rw-r--r--modules/io_codec/examples/echo_server.cpp162
1 files changed, 162 insertions, 0 deletions
diff --git a/modules/io_codec/examples/echo_server.cpp b/modules/io_codec/examples/echo_server.cpp
new file mode 100644
index 0000000..f7f833f
--- /dev/null
+++ b/modules/io_codec/examples/echo_server.cpp
@@ -0,0 +1,162 @@
+#include "../c++/io_peer.hpp"
+
+#include <iostream>
+
+#include "echo.hpp"
+
+saw::error_or<void> handle_echo_write(saw::io_stream& rmt_clt, message& state, uint64_t tbw){
+ auto eov = rmt_clt.write(&state.data[state.already_written], tbw);
+ if(eov.is_error()){
+ return std::move(eov.get_error());
+ }
+
+ auto val = eov.get_value();
+ state.already_written += val;
+ if(state.already_written > state.already_read){
+ exit(-1);
+ }
+
+ return saw::void_t{};
+}
+
+void handle_echo_message(saw::io_stream& rmt_clt, bool& keep_running, message& state){
+ rmt_clt.read_ready().then([&](){
+ for(;;){
+ uint64_t tbr = state.data.size() < state.already_read ? 0: state.data.size() - state.already_read;
+ if(tbr == 0){
+ exit(-1);
+ }
+ auto eov = rmt_clt.read(&state.data[state.already_read], tbr);
+
+ if(eov.is_error()){
+ auto& err = eov.get_error();
+ if(err.is_critical()){
+ std::cerr<<err.get_category()<<std::endl;
+ exit(err.get_id());
+ }else{
+ break;
+ }
+ }
+ auto read_bytes = eov.get_value();
+ if(read_bytes == 0u){
+ exit(-1);
+ }
+
+ bool trigger_write = (state.already_read == state.already_written);
+
+ state.already_read += read_bytes;
+ if(state.already_read > state.data.size()){
+ state.already_read = state.data.size();
+ }
+ if(trigger_write){
+ auto eov = handle_echo_write(rmt_clt, state, state.already_read - state.already_written);
+ if(eov.is_error()){
+ auto& err = eov.get_error();
+ if(err.is_critical()){
+ std::cerr<<err.get_category()<<std::endl;
+ exit(err.get_id());
+ }else {
+ break;
+ }
+ }
+ }
+ }
+ }).detach();
+
+ rmt_clt.write_ready().then([&](){
+ for(;;){
+ if(state.already_read < state.already_written){
+ exit(-1);
+ }
+ uint64_t tbw = state.already_read - state.already_written;
+ if(tbw == 0){
+ break;
+ }
+
+ auto eov = handle_echo_write(rmt_clt, state, tbw);
+ if(eov.is_error()){
+ auto& err = eov.get_error();
+ if(err.is_critical()){
+ std::cerr<<err.get_category()<<std::endl;
+ exit(err.get_id());
+ }else {
+ break;
+ }
+ }
+ }
+ }).detach();
+
+ rmt_clt.on_read_disconnected().then([&](){
+ keep_running = false;
+ }).detach();
+}
+
+int main(){
+ auto eo_aio = saw::setup_async_io();
+ if(eo_aio.is_error()){
+ auto& err = eo_aio.get_error();
+ std::cerr<<err.get_message()<<std::endl;
+ return err.get_id();
+ }
+ auto& aio = eo_aio.get_value();
+ /**
+ * Make the event loop the current event loop on this thread
+ */
+ saw::wait_scope wait_scope{aio.event_loop};
+
+ bool keep_running = true;
+ aio.event_port.on_signal(saw::Signal::Terminate).then([&keep_running](){
+ keep_running = false;
+ }).detach();
+
+ auto& network = aio.io->get_network();
+ saw::own<saw::network_address> addr = nullptr;
+ saw::own<saw::server> srv = nullptr;
+ saw::own<saw::io_stream> remote_client = nullptr;
+
+ message msg_state;
+
+ std::cout<<"Starting to resolve address"<<std::endl;
+ /**
+ * Try to resolve address. If resolved
+ */
+ network.resolve_address("127.0.0.1", 4322).then([&](auto net_addr){
+ std::cout<<"Resolved address"<<std::endl;
+ addr = std::move(net_addr);
+ srv = network.listen(*addr);
+ if(srv){
+ srv->accept().then([&](auto client) -> saw::error_or<void>{
+
+ if(!remote_client){
+ std::cout<<"Accepted client"<<std::endl;
+ remote_client = std::move(client);
+
+ if(remote_client){
+ std::cout<<"Spinning up handler"<<std::endl;
+ handle_echo_message(*remote_client, keep_running, msg_state);
+ }else{
+ keep_running = false;
+ }
+ }
+ return saw::make_error<saw::err::critical>();
+ }).detach();
+ }else{
+ keep_running = false;
+ }
+ }).detach([&](auto err) {
+ std::cout<<"Failed to resolve address: "<<err.get_category()<<":"<<err.get_message()<<std::endl;
+ keep_running = false;
+ return err;
+ });
+
+ std::cout<<"Entering waiting loop"<<std::endl;
+
+ wait_scope.poll();
+ while(keep_running){
+ wait_scope.wait(std::chrono::seconds{5});
+ }
+
+ std::cout<<"\n\nShutting down echo server"<<std::endl;
+
+ return 0;
+}