Skip to content
This repository was archived by the owner on Feb 23, 2020. It is now read-only.

Commit cd8cca6

Browse files
committed
Implement channels.
1 parent 38d89e4 commit cd8cca6

File tree

1 file changed

+132
-43
lines changed

1 file changed

+132
-43
lines changed

src/main.cpp

+132-43
Original file line numberDiff line numberDiff line change
@@ -1,65 +1,154 @@
1+
#include <set>
12
#include <websocketpp/config/asio_no_tls.hpp>
23
#include <websocketpp/server.hpp>
3-
44
#include <iostream>
55

6-
typedef websocketpp::server<websocketpp::config::asio> server;
76

7+
struct connection_data {
8+
int session;
9+
std::string room;
10+
};
11+
12+
struct custom_config : public websocketpp::config::asio {
13+
// Default settings from our core config
14+
typedef websocketpp::config::asio core;
15+
16+
typedef core::concurrency_type concurrency_type;
17+
typedef core::request_type request_type;
18+
typedef core::response_type response_type;
19+
typedef core::message_type message_type;
20+
typedef core::con_msg_manager_type con_msg_manager_type;
21+
typedef core::endpoint_msg_manager_type endpoint_msg_manager_type;
22+
typedef core::alog_type alog_type;
23+
typedef core::elog_type elog_type;
24+
typedef core::rng_type rng_type;
25+
typedef core::transport_type transport_type;
26+
typedef core::endpoint_base endpoint_base;
27+
28+
// Set a custom connection_base class to handle indetification.
29+
typedef connection_data connection_base;
30+
};
31+
32+
typedef websocketpp::server<custom_config> server;
33+
typedef server::connection_ptr connection_ptr;
34+
typedef server::message_ptr message_ptr;
35+
typedef server::connection_ptr connection_ptr;
36+
37+
using websocketpp::connection_hdl;
838
using websocketpp::lib::placeholders::_1;
939
using websocketpp::lib::placeholders::_2;
1040
using websocketpp::lib::bind;
1141

12-
// pull out the type of messages sent by our config
13-
typedef server::message_ptr message_ptr;
1442

15-
// Define a callback to handle incoming messages
16-
void on_message(server* s, websocketpp::connection_hdl hdl, message_ptr msg) {
17-
try {
18-
s->send(hdl, msg->get_payload(), msg->get_opcode());
19-
} catch (websocketpp::exception const & e) {
20-
std::cout << "Error: "
21-
<< "(" << e.what() << ")" << std::endl;
43+
// This class will be heart of our app.
44+
class EchoServer
45+
{
46+
public:
47+
EchoServer()
48+
{
49+
// Try to not fail. Please. I have faith on you.
50+
try {
51+
// Set logging settings
52+
_server.set_access_channels(websocketpp::log::alevel::none);
53+
_server.clear_access_channels(websocketpp::log::alevel::none);
54+
_server.init_asio();
55+
56+
// Message handler
57+
_server.set_open_handler(bind(&EchoServer::onOpen,this,::_1));
58+
_server.set_close_handler(bind(&EchoServer::onClose,this,::_1));
59+
_server.set_message_handler(bind(&EchoServer::onMessage,this,::_1,::_2));
60+
_server.listen(80);
61+
62+
// Tell something :)
63+
std::cout << "Starting GameTactic CPP Echo server...\n";
64+
std::cout << "--------------------------------------------------------\n";
65+
std::cout << "| Copyright 2019 Niko Granö <niko@ironlions.fi> |\n";
66+
std::cout << "| Licensed under GPLv3. |\n";
67+
std::cout << "| https://gametactic.eu |\n";
68+
std::cout << "--------------------------------------------------------\n\n";
69+
70+
// Start the server.
71+
_server.start_accept();
72+
_server.run();
73+
} catch (websocketpp::exception const & e) {
74+
std::cout << e.what() << std::endl;
75+
} catch (...) {
76+
std::cout << "Error: " << std::endl;
77+
}
2278
}
23-
}
2479

80+
// Callback to handle incoming messages
81+
void onMessage(connection_hdl conn, message_ptr msg) {
82+
// Get connection
83+
connection_ptr ptr = _server.get_con_from_hdl(conn);
84+
85+
// Check if client is requesting to join.
86+
if (msg->get_payload().substr(0,5) == "join:") {
87+
std::string room = msg->get_payload().substr(5);
88+
ptr->room = room;
89+
std::stringstream ss;
90+
ss << "{\"success\":\"Room " << room << " selected.\"}";
91+
ptr->send(ss.str());
92+
93+
return;
94+
}
95+
96+
if (ptr->room.empty()) {
97+
ptr->send("{\"error\":\"No room selected.\"}");
98+
99+
return;
100+
}
101+
102+
try {
103+
for (auto c : _connections) {
104+
connection_ptr _ptr = _server.get_con_from_hdl(c);
105+
if (_ptr->room == ptr->room) {
106+
_server.send(c,msg);
107+
}
108+
}
109+
} catch (websocketpp::exception const &e) {
110+
std::cout << "Error: " << "(" << e.what() << ")" << std::endl;
111+
}
112+
}
113+
114+
// Callback to handle new connections
115+
void onOpen(connection_hdl conn) {
116+
connection_ptr ptr = _server.get_con_from_hdl(conn);
117+
ptr->session = _session++;
118+
_connections.insert(conn);
119+
}
120+
121+
// Callback to handle closing connection
122+
void onClose(connection_hdl conn) {
123+
connection_ptr ptr = _server.get_con_from_hdl(conn);
124+
_connections.erase(conn);
125+
}
126+
127+
private:
128+
typedef std::set<connection_hdl,std::owner_less<connection_hdl>> con_list;
129+
130+
// Create a server and list for connections.
131+
server _server;
132+
con_list _connections;
133+
134+
// Every client has own id to help identify.
135+
int _session;
136+
137+
// Rooms
138+
//std::map<int, string::string> _rooms;
139+
//std::vector<std::map<std::string, std::string>> _rooms;
140+
};
141+
142+
// Basic signal hander
25143
void signalHandler( int signum ) {
26144
std::cout << "Interrupt signal (" << signum << ") received.\n";
27145
exit(signum);
28146
}
29147

30-
31148
int main() {
32149
// Handle signals.
33150
signal(SIGINT, signalHandler);
34151

35-
// Create a server endpoint
36-
server _server;
37-
38-
try {
39-
// Set logging settings
40-
_server.set_access_channels(websocketpp::log::alevel::none);
41-
_server.clear_access_channels(websocketpp::log::alevel::none);
42-
_server.init_asio();
43-
44-
// Message handler
45-
_server.set_message_handler(bind(&on_message,&_server,::_1,::_2));
46-
_server.listen(80);
47-
48-
// Tell something :)
49-
std::cout << "Starting GameTactic CPP Echo server...\n";
50-
std::cout << "--------------------------------------------------------------------------------\n";
51-
std::cout << "| Copyright 2019 Niko Granö <niko@ironlions.fi> |\n";
52-
std::cout << "| Licensed under GPLv3. |\n";
53-
std::cout << "| https://gametactic.eu |\n";
54-
std::cout << "--------------------------------------------------------------------------------\n\n";
55-
56-
// Start the server.
57-
// First start itself, second start asio.
58-
_server.start_accept();
59-
_server.run();
60-
} catch (websocketpp::exception const & e) {
61-
std::cout << e.what() << std::endl;
62-
} catch (...) {
63-
std::cout << "Error: " << std::endl;
64-
}
152+
// Start app.
153+
EchoServer srv;
65154
}

0 commit comments

Comments
 (0)