Line data Source code
1 : // Copyright (c) 2012-2021 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 : // self
21 : //
22 : #include "catch_main.h"
23 :
24 :
25 : // eventdispatcher lib
26 : //
27 : #include <eventdispatcher/local_dgram_server_message_connection.h>
28 : #include <eventdispatcher/dispatcher.h>
29 :
30 :
31 : // C lib
32 : //
33 : #include <unistd.h>
34 :
35 :
36 :
37 :
38 : namespace
39 : {
40 :
41 :
42 :
43 : class unix_dgram_server;
44 :
45 :
46 :
47 : // to receive datagram, we need to create a server, so event the client
48 : // is a server... (if you want back and forth communication over datagram
49 : // that is)
50 : //
51 1 : class unix_dgram_client
52 : : public ed::local_dgram_server_message_connection
53 : {
54 : public:
55 : typedef std::shared_ptr<unix_dgram_client> pointer_t;
56 :
57 : unix_dgram_client(
58 : addr::unix const & address);
59 :
60 : void set_server_address(addr::unix const & server_address);
61 :
62 : void send_hello();
63 : void msg_hi(ed::message & msg);
64 : void msg_reply_with_unknown(ed::message & msg);
65 :
66 : private:
67 : ed::dispatcher<unix_dgram_client>::pointer_t
68 : f_dispatcher = ed::dispatcher<unix_dgram_client>::pointer_t();
69 : addr::unix f_server_address = addr::unix();
70 : };
71 :
72 :
73 :
74 :
75 : class unix_dgram_server
76 : : public ed::local_dgram_server_message_connection
77 : {
78 : public:
79 : typedef std::shared_ptr<unix_dgram_server> pointer_t;
80 :
81 : unix_dgram_server(addr::unix const & address);
82 : ~unix_dgram_server();
83 :
84 : void set_client_address(addr::unix const & server_address);
85 : void done();
86 :
87 : void msg_hello(ed::message & msg);
88 : void msg_down(ed::message & msg);
89 : void msg_reply_with_unknown(ed::message & msg);
90 :
91 : // connection implementation
92 : //
93 : //virtual void process_accept() override;
94 :
95 : private:
96 : ed::dispatcher<unix_dgram_server>::pointer_t
97 : f_dispatcher = ed::dispatcher<unix_dgram_server>::pointer_t();
98 : addr::unix f_client_address = addr::unix();
99 : };
100 :
101 :
102 :
103 :
104 :
105 2 : ed::dispatcher<unix_dgram_client>::dispatcher_match::vector_t const g_unix_dgram_client_messages =
106 : {
107 : {
108 : "HI"
109 : , &unix_dgram_client::msg_hi
110 : },
111 :
112 : // ALWAYS LAST
113 : {
114 : nullptr
115 : , &unix_dgram_client::msg_reply_with_unknown
116 : , &ed::dispatcher<unix_dgram_client>::dispatcher_match::always_match
117 : }
118 : };
119 :
120 2 : ed::dispatcher<unix_dgram_server>::dispatcher_match::vector_t const g_unix_dgram_server_messages =
121 : {
122 : {
123 : "HELLO"
124 : , &unix_dgram_server::msg_hello
125 : },
126 : {
127 : "DOWN"
128 : , &unix_dgram_server::msg_down
129 : },
130 :
131 : // ALWAYS LAST
132 : {
133 : nullptr
134 : , &unix_dgram_server::msg_reply_with_unknown
135 : , &ed::dispatcher<unix_dgram_server>::dispatcher_match::always_match
136 : }
137 : };
138 :
139 :
140 :
141 :
142 :
143 1 : unix_dgram_client::unix_dgram_client(addr::unix const & address)
144 : : local_dgram_server_message_connection(
145 : address
146 : , false
147 : , true
148 : , true)
149 : , f_dispatcher(new ed::dispatcher<unix_dgram_client>(
150 : this
151 1 : , g_unix_dgram_client_messages))
152 : {
153 1 : set_name("unix-dgram-client");
154 : #ifdef _DEBUG
155 1 : f_dispatcher->set_trace();
156 : #endif
157 1 : set_dispatcher(f_dispatcher);
158 1 : }
159 :
160 :
161 1 : void unix_dgram_client::set_server_address(addr::unix const & server_address)
162 : {
163 1 : f_server_address = server_address;
164 1 : }
165 :
166 :
167 1 : void unix_dgram_client::send_hello()
168 : {
169 : // send the HELLO message, since we're not going to be connected yet
170 : // we ask for the permanent connection to cache the message
171 : //
172 2 : ed::message hello;
173 1 : hello.set_command("HELLO");
174 1 : send_message(f_server_address, hello);
175 1 : }
176 :
177 :
178 1 : void unix_dgram_client::msg_hi(ed::message & msg)
179 : {
180 1 : CATCH_REQUIRE(msg.get_command() == "HI");
181 :
182 2 : ed::message down;
183 1 : down.set_command("DOWN");
184 1 : send_message(f_server_address, down);
185 :
186 : // we can immediately remove the connection since the send_message()
187 : // is immediate in case of UDP
188 : //
189 1 : ed::communicator::instance()->remove_connection(shared_from_this());
190 1 : }
191 :
192 :
193 0 : void unix_dgram_client::msg_reply_with_unknown(ed::message & msg)
194 : {
195 0 : snap::NOT_USED(msg);
196 0 : }
197 :
198 :
199 :
200 :
201 :
202 :
203 :
204 :
205 :
206 :
207 :
208 :
209 :
210 1 : unix_dgram_server::unix_dgram_server(addr::unix const & address)
211 : : local_dgram_server_message_connection(
212 : address
213 : , false
214 : , true
215 : , true)
216 : , f_dispatcher(new ed::dispatcher<unix_dgram_server>(
217 : this
218 1 : , g_unix_dgram_server_messages))
219 : {
220 1 : set_name("unix-dgram-server");
221 : #ifdef _DEBUG
222 1 : f_dispatcher->set_trace();
223 : #endif
224 1 : set_dispatcher(f_dispatcher);
225 1 : }
226 :
227 :
228 1 : unix_dgram_server::~unix_dgram_server()
229 : {
230 1 : }
231 :
232 :
233 1 : void unix_dgram_server::set_client_address(addr::unix const & server_address)
234 : {
235 1 : f_client_address = server_address;
236 1 : }
237 :
238 :
239 0 : void unix_dgram_server::done()
240 : {
241 0 : ed::communicator::instance()->remove_connection(shared_from_this());
242 0 : }
243 :
244 :
245 1 : void unix_dgram_server::msg_hello(ed::message & msg)
246 : {
247 1 : CATCH_REQUIRE(msg.get_command() == "HELLO");
248 1 : snap::NOT_USED(msg);
249 :
250 2 : ed::message hi;
251 1 : hi.set_command("HI");
252 1 : send_message(f_client_address, hi);
253 1 : }
254 :
255 :
256 1 : void unix_dgram_server::msg_down(ed::message & msg)
257 : {
258 1 : CATCH_REQUIRE(msg.get_command() == "DOWN");
259 :
260 1 : ed::communicator::instance()->remove_connection(shared_from_this());
261 1 : }
262 :
263 :
264 0 : void unix_dgram_server::msg_reply_with_unknown(ed::message & msg)
265 : {
266 0 : snap::NOT_USED(msg);
267 0 : }
268 :
269 :
270 :
271 :
272 :
273 :
274 : } // no name namespace
275 :
276 :
277 :
278 3 : CATCH_TEST_CASE("local_dgram_messaging", "[local-dgram]")
279 : {
280 2 : CATCH_START_SECTION("Create a Server, Client, Connect & Send Messages")
281 : {
282 2 : ed::communicator::pointer_t communicator(ed::communicator::instance());
283 :
284 2 : std::string server_name("test-unix-dgram-server");
285 1 : unlink(server_name.c_str());
286 1 : addr::unix server_address(server_name);
287 :
288 2 : std::string client_name("test-unix-dgram-client");
289 1 : unlink(client_name.c_str());
290 1 : addr::unix client_address(client_name);
291 :
292 2 : unix_dgram_server::pointer_t server(std::make_shared<unix_dgram_server>(server_address));
293 1 : server->set_client_address(client_address);
294 1 : communicator->add_connection(server);
295 :
296 2 : unix_dgram_client::pointer_t client(std::make_shared<unix_dgram_client>(client_address));
297 1 : client->set_server_address(server_address);
298 1 : communicator->add_connection(client);
299 :
300 1 : client->send_hello();
301 :
302 1 : communicator->run();
303 : }
304 : CATCH_END_SECTION()
305 7 : }
306 :
307 :
308 : // vim: ts=4 sw=4 et
|