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 3 : 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 5 : }
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 3 : 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 3 : 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 3 : set_name("unix-dgram-server");
201 : #ifdef _DEBUG
202 1 : f_dispatcher->set_trace();
203 : #endif
204 1 : set_dispatcher(f_dispatcher);
205 :
206 7 : 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 7 : }
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 3 : 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 3 : 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 3 : 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
|