aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorC-o-r-E <can.of.tuna@gmail.com>2023-07-09 17:29:56 -0400
committerGarrett D'Amore <garrett@damore.org>2023-08-23 11:20:01 -0700
commit52885b6e5af3174e7d367dddcb02b9f50849f191 (patch)
tree9866484932e46bac097a3eaf731e9c0e320193fe
parent096ad744e4858136d70eabe0bbd4f6d70d637da2 (diff)
downloadnng-52885b6e5af3174e7d367dddcb02b9f50849f191.tar.gz
nng-52885b6e5af3174e7d367dddcb02b9f50849f191.tar.bz2
nng-52885b6e5af3174e7d367dddcb02b9f50849f191.zip
Add forwarder demo
-rw-r--r--demo/pubsub_forwarder/CMakeLists.txt18
-rw-r--r--demo/pubsub_forwarder/README.adoc62
-rw-r--r--demo/pubsub_forwarder/pubsub_forwarder.c86
3 files changed, 166 insertions, 0 deletions
diff --git a/demo/pubsub_forwarder/CMakeLists.txt b/demo/pubsub_forwarder/CMakeLists.txt
new file mode 100644
index 00000000..821e05c0
--- /dev/null
+++ b/demo/pubsub_forwarder/CMakeLists.txt
@@ -0,0 +1,18 @@
+# This software is supplied under the terms of the MIT License, a
+# copy of which should be located in the distribution where this
+# file was obtained (LICENSE.txt). A copy of the license may also be
+# found online at https://opensource.org/licenses/MIT.
+
+cmake_minimum_required(VERSION 3.10)
+project(pubsub_forwarder C)
+
+# Find the nng library
+find_package(nng REQUIRED)
+
+# Add the executable target
+add_executable(pubsub_forwarder pubsub_forwarder.c)
+
+target_compile_options(pubsub_forwarder PRIVATE -Wall -Wextra -Wpedantic -Werror -O2)
+
+# Link against the nng library
+target_link_libraries(pubsub_forwarder PRIVATE nng)
diff --git a/demo/pubsub_forwarder/README.adoc b/demo/pubsub_forwarder/README.adoc
new file mode 100644
index 00000000..55832b9a
--- /dev/null
+++ b/demo/pubsub_forwarder/README.adoc
@@ -0,0 +1,62 @@
+= PubSub Forwarder
+
+This is a trivial example of a forwarder/proxy for the pub/sub pattern.
+
+The concept is as follows: the forwarder will listen for connections on
+both a front-end port and a back-end port. The front-end will act as a
+subscriber so that publishers can publish to it. The back-end will act
+as a publisher so that subscribers can subscribe to it. The front-end
+then forwards to the back end.
+
+== Compiling
+
+CMake with ninja-build is simplest:
+
+[source, bash]
+----
+cmake -GNinja -B build
+cd build
+ninja
+----
+
+Or if you prefer a traditional approach,
+the following is an example typical of UNIX and similar systems like
+Linux and macOS may appeal:
+
+[source, bash]
+----
+export CPPFLAGS="-I /usr/local/include"
+export LDFLAGS="-L /usr/local/lib -lnng"
+export CC="cc"
+${CC} ${CPPFLAGS} pubsub_forwarder.c -o pubsub_forwarder ${LDFLAGS}
+----
+
+== Running
+
+An example setup for running this example would involve the following:
+
+. Step 1: Run this example binary (in the background or a terminal, etc)
+. Step 2: In a new terminal, run the following
+
+[source, bash]
+----
+nngcat --sub --dial "tcp://localhost:3328" --quoted
+----
+
+. Step 3: In a second terminal, run the same command again to give us two subscribers
+
+[source, bash]
+----
+nngcat --sub --dial "tcp://localhost:3328" --quoted
+----
+
+
+. In a third terminal, run the following to publish a counter
+
+[source, bash]
+----
+for n in $(seq 0 99); do nngcat --pub --dial "tcp://localhost:3327" --data "$n"; done
+----
+
+
+
diff --git a/demo/pubsub_forwarder/pubsub_forwarder.c b/demo/pubsub_forwarder/pubsub_forwarder.c
new file mode 100644
index 00000000..dc18cc64
--- /dev/null
+++ b/demo/pubsub_forwarder/pubsub_forwarder.c
@@ -0,0 +1,86 @@
+//
+// This software is supplied under the terms of the MIT License, a
+// copy of which should be located in the distribution where this
+// file was obtained (LICENSE.txt). A copy of the license may also be
+// found online at https://opensource.org/licenses/MIT.
+//
+
+//
+// Forwarder example based on https://github.com/C-o-r-E/nng_pubsub_proxy
+//
+// This example shows how to use raw sockets to set up a forwarder or proxy for pub/sub.
+//
+// An example setup for running this example would involve the following:
+//
+// - Run this example binary (in the background or a terminal, etc)
+// - In a new terminal, run `nngcat --sub --dial "tcp://localhost:3328" --quoted`
+// - In a second terminal, run `nngcat --sub --dial "tcp://localhost:3328" --quoted`
+// - In a third terminal, run `for n in $(seq 0 99); do nngcat --pub --dial "tcp://localhost:3327" --data "$n"; done`
+//
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <nng/nng.h>
+#include <nng/protocol/pubsub0/sub.h>
+#include <nng/protocol/pubsub0/pub.h>
+
+#define PROXY_FRONT_URL "tcp://localhost:3327"
+#define PROXY_BACK_URL "tcp://localhost:3328"
+
+void panic_on_error(int should_panic, const char* format, ...)
+{
+ if (should_panic)
+ {
+ va_list args;
+ va_start(args, format);
+ vprintf(format, args);
+ va_end(args);
+ exit(EXIT_FAILURE);
+ }
+}
+
+int main()
+{
+ nng_socket sock_front_end = NNG_SOCKET_INITIALIZER;
+ nng_socket sock_back_end = NNG_SOCKET_INITIALIZER;
+ int ret = 0;
+
+ /*
+ First we need some nng sockets. Not to be confused with network sockets
+ */
+ ret = nng_sub0_open_raw(&sock_front_end);
+ panic_on_error(ret, "Failed to open front end socket\n");
+
+ ret = nng_pub0_open_raw(&sock_back_end);
+ panic_on_error(ret, "Failed to open back end socket\n");
+
+ /*
+ Now we need to set up a listener for each socket so that they have addresses
+ */
+
+ nng_listener front_ls = NNG_LISTENER_INITIALIZER;
+ nng_listener back_ls = NNG_LISTENER_INITIALIZER;
+
+ ret = nng_listener_create(&front_ls, sock_front_end, PROXY_FRONT_URL);
+ panic_on_error(ret, "Failed to create front listener\n");
+
+ ret = nng_listener_create(&back_ls, sock_back_end, PROXY_BACK_URL);
+ panic_on_error(ret, "Failed to create back listener\n");
+
+ ret = nng_listener_start(front_ls, 0);
+ panic_on_error(ret, "Failed to start front listener\n");
+
+ ret = nng_listener_start(back_ls, 0);
+ panic_on_error(ret, "Failed to start back listener\n");
+
+ /*
+ Finally let nng do the forwarding/proxying
+ */
+
+ ret = nng_device(sock_front_end, sock_back_end);
+ panic_on_error(ret, "nng_device returned %d: %s\n", ret, nng_strerror(ret));
+
+ printf("done");
+ return 0;
+} \ No newline at end of file