summaryrefslogtreecommitdiff
path: root/modules/io/examples/echo_server.cpp
blob: a158368da0ce78c43f0b04d80a3d5ba1543df71a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#include "../c++/io.hpp"

#include <iostream>

#include "echo.hpp"

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[0], tbr);

			if(eov.is_error()){
				auto& err = eov.get_error();
				if(err.is_critical()){
					exit(err.get_id());
				}
			}
		}
	}).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){
					remote_client = std::move(client);

					if(remote_client){
						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{60});
	}

	std::cout<<"\n\nShutting down echo server"<<std::endl;

	return 0;
}