summaryrefslogtreecommitdiff
path: root/modules/io_codec/examples/peer_echo_server.cpp
blob: 184951766923a862a403666997f7a1115322272d (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
96
97
98
99
#include "echo.hpp"

#include "../c++/io_peer.hpp"

#include <forstio/codec/transport.hpp>

#include <iostream>

int main(){
	using namespace saw;

	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{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();

	auto eo_addr = network.resolve_address(saw::echo_address, saw::echo_port).take();
	if(eo_addr.is_error()){
		return -1;
	}
	auto& addr = eo_addr.get_value();

	data<sch::Echo> nat_echo{"hello"};
	data<sch::Echo, encode::KelSimple> simple_echo;
	codec<sch::Echo, encode::KelSimple> simple_codec;

	{
		auto eov = simple_codec.encode(nat_echo, simple_echo);
		if(eov.is_error()){
			return -1;
		}
	}

	auto echo_srv = network.listen(*addr);
	if(!echo_srv){
		return -2;
	}

	echo_srv->accept().then([&](saw::own<saw::io_stream> client){
		if(!client){
			keep_running = false;
			return;
		}
		auto echo_stream = saw::heap<saw::async_io_stream>(std::move(client));
		auto echo_peer_stream_p = saw::new_streaming_io_peer<sch::Echo, sch::Echo, trans::FixedLength<8u>, encode::KelSimple, ring_buffer>(std::move(echo_stream));

		std::cout<<"Connected client"<<std::endl;
		auto peer_str = echo_peer_stream_p.first.get();
		
		echo_peer_stream_p.second.then([&,peer_str](auto simp_resp) -> error_or<void> {
			data<sch::Echo> nat_resp;
			{
				auto eov = simple_codec.decode(simp_resp, nat_resp);
				if(eov.is_error()){
					std::cerr<<"Failed to decode"<<std::endl;
					return eov;
				}
			}
			for(uint64_t i = 0u; i < nat_resp.size(); ++i){
				std::cout<<nat_resp.at(i);
			}
			std::cout<<std::endl;

			{
				auto eo_send = peer_str->send(std::move(simp_resp));
				if(eo_send.is_error()){
					auto& err = eo_send.get_error();
					return std::move(err);
				}
			}
			return make_void();
		}).detach();
	
		peer_str->on_disconnected().attach(std::move(echo_peer_stream_p.first)).then([]() -> error_or<void>{
			std::cout<<"Disconnected client"<<std::endl;
			return make_error<err::critical>("Destroy pipeline on purpose :>");
		}).detach();
	}).detach();

	while(keep_running){
		wait.wait(std::chrono::seconds{1u});
	}

	return 0;
}