Line data Source code
1 : // Copyright (c) 2012-2024 Made to Order Software Corp. All Rights Reserved 2 : // 3 : // https://snapwebsites.org/project/eventdispatcher 4 : // contact@m2osw.com 5 : // 6 : // This program is free software; you can redistribute it and/or modify 7 : // it under the terms of the GNU General Public License as published by 8 : // the Free Software Foundation; either version 2 of the License, or 9 : // (at your option) any later version. 10 : // 11 : // This program is distributed in the hope that it will be useful, 12 : // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 : // GNU General Public License for more details. 15 : // 16 : // You should have received a copy of the GNU General Public License along 17 : // with this program; if not, write to the Free Software Foundation, Inc., 18 : // 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 : 20 : // test standalone header 21 : // 22 : #include <eventdispatcher/local_dgram_server_message_connection.h> 23 : 24 : 25 : // self 26 : // 27 : #include "catch_main.h" 28 : 29 : 30 : // eventdispatcher 31 : // 32 : #include <eventdispatcher/communicator.h> 33 : #include <eventdispatcher/dispatcher.h> 34 : 35 : 36 : // C 37 : // 38 : #include <unistd.h> 39 : 40 : 41 : // last include 42 : // 43 : #include <snapdev/poison.h> 44 : 45 : 46 : 47 : 48 : namespace 49 : { 50 : 51 : 52 : 53 : class unix_dgram_server; 54 : 55 : 56 : 57 : // to receive datagram, we need to create a server, so event the client 58 : // is a server... (if you want back and forth communication over datagram 59 : // that is) 60 : // 61 : class unix_dgram_client 62 : : public ed::local_dgram_server_message_connection 63 : { 64 : public: 65 : typedef std::shared_ptr<unix_dgram_client> pointer_t; 66 : 67 : unix_dgram_client(addr::addr_unix const & address); 68 : 69 : void set_server_address(addr::addr_unix const & server_address); 70 : 71 : void send_hello(); 72 : void msg_hi(ed::message & msg); 73 : void msg_reply_with_unknown(ed::message & msg); 74 : 75 : private: 76 : ed::dispatcher::pointer_t 77 : f_dispatcher = ed::dispatcher::pointer_t(); 78 : addr::addr_unix f_server_address = addr::addr_unix(); 79 : }; 80 : 81 : 82 : 83 : 84 : class unix_dgram_server 85 : : public ed::local_dgram_server_message_connection 86 : { 87 : public: 88 : typedef std::shared_ptr<unix_dgram_server> pointer_t; 89 : 90 : unix_dgram_server(addr::addr_unix const & address); 91 : ~unix_dgram_server(); 92 : 93 : void set_client_address(addr::addr_unix const & server_address); 94 : void done(); 95 : 96 : void msg_hello(ed::message & msg); 97 : void msg_down(ed::message & msg); 98 : void msg_reply_with_unknown(ed::message & msg); 99 : 100 : // connection implementation 101 : // 102 : //virtual void process_accept() override; 103 : 104 : private: 105 : ed::dispatcher::pointer_t 106 : f_dispatcher = ed::dispatcher::pointer_t(); 107 : addr::addr_unix f_client_address = addr::addr_unix(); 108 : }; 109 : 110 : 111 : 112 : 113 : 114 : 115 : 116 : 117 : 118 : 119 : 120 1 : unix_dgram_client::unix_dgram_client(addr::addr_unix const & address) 121 : : local_dgram_server_message_connection( 122 : address 123 : , false 124 : , true 125 : , true) 126 1 : , f_dispatcher(std::make_shared<ed::dispatcher>(this)) 127 : { 128 1 : set_name("unix-dgram-client"); 129 : #ifdef _DEBUG 130 1 : f_dispatcher->set_trace(); 131 : #endif 132 1 : set_dispatcher(f_dispatcher); 133 : 134 6 : f_dispatcher->add_matches({ 135 2 : DISPATCHER_MATCH("HI", &unix_dgram_client::msg_hi), 136 : 137 : // ALWAYS LAST 138 2 : DISPATCHER_CATCH_ALL() 139 : }); 140 1 : } 141 : 142 : 143 1 : void unix_dgram_client::set_server_address(addr::addr_unix const & server_address) 144 : { 145 1 : f_server_address = server_address; 146 1 : } 147 : 148 : 149 1 : void unix_dgram_client::send_hello() 150 : { 151 : // send the HELLO message, since we're not going to be connected yet 152 : // we ask for the permanent connection to cache the message 153 : // 154 1 : ed::message hello; 155 1 : hello.set_command("HELLO"); 156 1 : send_message(f_server_address, hello); 157 2 : } 158 : 159 : 160 1 : void unix_dgram_client::msg_hi(ed::message & msg) 161 : { 162 1 : CATCH_REQUIRE(msg.get_command() == "HI"); 163 : 164 1 : ed::message down; 165 1 : down.set_command("DOWN"); 166 1 : send_message(f_server_address, down); 167 : 168 : // we can immediately remove the connection since the send_message() 169 : // is immediate in case of UDP 170 : // 171 1 : ed::communicator::instance()->remove_connection(shared_from_this()); 172 2 : } 173 : 174 : 175 0 : void unix_dgram_client::msg_reply_with_unknown(ed::message & msg) 176 : { 177 0 : snapdev::NOT_USED(msg); 178 0 : } 179 : 180 : 181 : 182 : 183 : 184 : 185 : 186 : 187 : 188 : 189 : 190 : 191 : 192 1 : unix_dgram_server::unix_dgram_server(addr::addr_unix const & address) 193 : : local_dgram_server_message_connection( 194 : address 195 : , false 196 : , true 197 : , true) 198 1 : , f_dispatcher(std::make_shared<ed::dispatcher>(this)) 199 : { 200 1 : set_name("unix-dgram-server"); 201 : #ifdef _DEBUG 202 1 : f_dispatcher->set_trace(); 203 : #endif 204 1 : set_dispatcher(f_dispatcher); 205 : 206 9 : f_dispatcher->add_matches({ 207 2 : DISPATCHER_MATCH("HELLO", &unix_dgram_server::msg_hello), 208 2 : DISPATCHER_MATCH("DOWN", &unix_dgram_server::msg_down), 209 : 210 : // ALWAYS LAST 211 2 : DISPATCHER_CATCH_ALL() 212 : }); 213 1 : } 214 : 215 : 216 1 : unix_dgram_server::~unix_dgram_server() 217 : { 218 1 : } 219 : 220 : 221 1 : void unix_dgram_server::set_client_address(addr::addr_unix const & server_address) 222 : { 223 1 : f_client_address = server_address; 224 1 : } 225 : 226 : 227 0 : void unix_dgram_server::done() 228 : { 229 0 : ed::communicator::instance()->remove_connection(shared_from_this()); 230 0 : } 231 : 232 : 233 1 : void unix_dgram_server::msg_hello(ed::message & msg) 234 : { 235 1 : CATCH_REQUIRE(msg.get_command() == "HELLO"); 236 1 : snapdev::NOT_USED(msg); 237 : 238 1 : ed::message hi; 239 1 : hi.set_command("HI"); 240 1 : send_message(f_client_address, hi); 241 2 : } 242 : 243 : 244 1 : void unix_dgram_server::msg_down(ed::message & msg) 245 : { 246 1 : CATCH_REQUIRE(msg.get_command() == "DOWN"); 247 : 248 1 : ed::communicator::instance()->remove_connection(shared_from_this()); 249 1 : } 250 : 251 : 252 0 : void unix_dgram_server::msg_reply_with_unknown(ed::message & msg) 253 : { 254 0 : snapdev::NOT_USED(msg); 255 0 : } 256 : 257 : 258 : 259 : 260 : 261 : 262 : } // no name namespace 263 : 264 : 265 : 266 1 : CATCH_TEST_CASE("local_dgram_messaging", "[local-dgram]") 267 : { 268 1 : CATCH_START_SECTION("Create a Server, Client, Connect & Send Messages") 269 : { 270 1 : ed::communicator::pointer_t communicator(ed::communicator::instance()); 271 : 272 2 : std::string server_name("test-unix-dgram-server"); 273 1 : unlink(server_name.c_str()); 274 1 : addr::addr_unix server_address(server_name); 275 : 276 2 : std::string client_name("test-unix-dgram-client"); 277 1 : unlink(client_name.c_str()); 278 1 : addr::addr_unix client_address(client_name); 279 : 280 1 : unix_dgram_server::pointer_t server(std::make_shared<unix_dgram_server>(server_address)); 281 1 : server->set_client_address(client_address); 282 1 : communicator->add_connection(server); 283 : 284 1 : unix_dgram_client::pointer_t client(std::make_shared<unix_dgram_client>(client_address)); 285 1 : client->set_server_address(server_address); 286 1 : communicator->add_connection(client); 287 : 288 1 : client->send_hello(); 289 : 290 1 : communicator->run(); 291 1 : } 292 1 : CATCH_END_SECTION() 293 1 : } 294 : 295 : 296 : // vim: ts=4 sw=4 et