cwzx / nngpp Goto Github PK
View Code? Open in Web Editor NEWC++ wrapper around the nanomsg NNG API
License: MIT License
C++ wrapper around the nanomsg NNG API
License: MIT License
Hi,
First of all, thank you for creating these bindings, I am excited to use them. I am having difficulties running your demo in the readme.
It seems like I am missing some sort of header / definition.
I have nanomsg installed and have nng/nng.h in my /usr/local/include.
A recursive grep shows that nng_strerror is in nng/nng.h
Calvin➜ include grep -rnw /usr/local/include -e "nng_strerror"
/usr/local/include/nng/nng.h:359:// nng_strerror returns a human readable string associated with the error
/usr/local/include/nng/nng.h:361:NNG_DECL const char *nng_strerror(int);
These are the only include you have in your demo but it seems to not compile.
#include <nngpp/nngpp.h>
#include <nngpp/protocol/req0.h>
#include <nngpp/protocol/rep0.h>
I have linked with libnanomsg as well but no luck.
I have the following test code which works:
#include <iostream>
#include <nngpp/nngpp.h>
#include <nngpp/protocol/push0.h>
#include <nngpp/protocol/pull0.h>
using namespace std;
int main()
{
const std::string addr{"ws://127.0.0.1:9999"};
nng::socket push_socket = nng::push::open();
nng::socket pull_socket = nng::pull::open();
pull_socket.listen(addr.data());
push_socket.dial(addr.data());
push_socket.send("love yourself?");
if(auto buffer = pull_socket.recv(); buffer)
cerr << "mama! the push socket told me to:\n\t" << (const char *) buffer.release() << '\n';
return 0;
}
I now try to split this code into two programs which are running on the same local area network. The IP address are taken from ip a
.
listener:
#include <iostream>
#include <nngpp/nngpp.h>
#include <nngpp/protocol/push0.h>
#include <nngpp/protocol/pull0.h>
using namespace std;
int main()
{
const std::string addr{"ws://127.0.0.1:9999"};
nng::socket pull_socket = nng::pull::open();
pull_socket.listen(addr.data());
if(auto buffer = pull_socket.recv(); buffer)
cerr << "mama! the push socket told me to:\n\t" << (const char *) buffer.release() << '\n';
return 0;
}
dialler:
#include <iostream>
#include "nngpp/nngpp.h"
#include "nngpp/protocol/push0.h"
#include "nngpp/protocol/pull0.h"
#include <string>
using namespace std;
int main()
{
const std::string addr{"ws://192.168.1.184:9999"};
nng::socket push_socket = nng::push::open();
push_socket.dial(addr.data());
push_socket.send("love yourself?");
return 0;
}
No matter which order I start the programs in, I get either a 'Connection refused' or a 'Connection shutdown' nng::exception from the dialler and the listener never receives the message. What am I doing wrong?
Hi,
Hope you are all well !
I am posting this issue more than a question ^^
I would like to implement that blog post with nng https://daniel-j-h.github.io/post/distributed-search-nanomsg-bond/ behing a restful server. More precisely, my goal is to survey several dockerized restful apis (respondents) with a surveyor embedded into a rest server.
Is it possible to do so ? I am stuck as I do not know how to start or create it ^^
Thanks a lot for any insights or inputs on that question/project.
Cheers,
X
Hi
Continuing with #10
I had similar issue, as well, using SWIG to interface some socket management functions like the following:
static nng::socket_view getIpcIndexSocket()
{
std::string sLane = "ipc:///aBridgeIndex";
nng::socket_view _socket(nng::survey::open());
// nng::set_opt_recv_timeout(_socket, 1000);
_socket.dial(sLane.c_str());
std::cout << "ipc index socket open" << std::endl;
return _socket;
}
And the Swig interface file (.i) declares:
nng::socket_view getIpcIndexSocket();
It compiles great now, but when importing the generated (python in this case) module, running that method throws an nng::exception
:
terminate called after throwing an instance of 'nng::exception'
what(): Object closed
right when the _socket.dial(...)
method is called.
Any clue about what's wrong with the code? There is nothing else going on in the Swig side, this is just a proof of concept, only method called.
Thanks
Originally posted by @webpolis in #10 (comment)
I only see a wrapper for int nng_device(nng_socket s1, nng_socket s2)
, but not void nng_device_aio(nng_aio *aio, nng_socket s1, nng_socket s2);
. Am I missing something? If not, are there plans to implement this in the future?
there is no pub/sub demo in nggpp project?
I'm new nngpp and I try to use pub/sub socket to write a demo,but it's not work.
the sub socket can't recv any msg.
my code as below:
server :
int main() try {
LOGD(TAG, "start");
nng::socket pub_socket = nng::pub::open();
pub_socket.listen("ipc://@pubsub.ipc");
while(1) {
LOGD(TAG, "pub data ");
pub_socket.send("BATTERY");
nng::msleep(1000);
}
LOGD(TAG, "end");
} catch(const nng::exception& e) {
return 1;
}
client:
int main() try {
LOGD(TAG, "start");
nng::socket sub_socket = nng::sub::open();
sub_socket.set_opt_string(NNG_OPT_SUB_SUBSCRIBE, "");
sub_socket.dial("ipc://@pubsub.ipc");
while(1) {
LOGD(TAG, "recv message start...");
nng::buffer msg = sub_socket.recv(NNG_FLAG_ALLOC);
LOGD(TAG, "recv message %s", msg.data());
nng::msleep(1000);
}
LOGD(TAG, "end");
} catch(const nng::exception& e) {
return 1;
}
Hi,
sorry if this issue is just a lack of my C++ understanding. But I could not find a way to send an ostringstream with the C++ interface.
std::ostringstream line;
line << "Hello World" << std::endl;
I tried different variants of passing the string that would not compile:
nng_sock.send(line.str());
I tried making a buffer view for it:
const std::string tmp = line.str();
const char* cstr = tmp.c_str();
nng_sock.send(nng::buffer(cstr,strlen(cstr)));
but that seems to try & free the pointer passed.
What I could get to work was calling the underlying nng_send
const std::string tmp = line.str();
const char* cstr = tmp.c_str();
int r = nng_send(nng_sock.get(),(void*)cstr,strlen(cstr),0);
if( r != 0 ) {
throw nng::exception(r,"nng_send");
}
Is there a better way to do it?
Preferably without copying the data in memory.
Hey everyone,
after a talk with gdamore I was informed, that nng only takes ownership of a msg
if the
associated send
operation was successful. If the operation wasn't successful the message
will no be free'd.
So I think the current move operator implementation in aio_view
should be deleted.
I can hopefully do a pull request for that in the coming days.
In the asynchronous REQREP demo, an exception is thrown in the callback [1]. However, the callback takes a direct function pointer [2] and nng may or may not have been built with -fexception
(or equivalent) [3]. There is a function-try-block which looks like it will catch errors in the callback but the thread running the callback originates inside of the nng threadpool - which is in C.
One way to solve this could be to not directly provide nng with the user-provided callback. Instead, have the aio
constructor take an std::function
and provide that to an argument to a "trampoline" function which catches any and all exceptions from the user-provided function. This trampoline is what you would then provide to nng as the AIO callback.
Hey, I tried using your library with nng 1.3.0 and ran
valgrind -v --leak-check=full --show-leak-kinds=all helloWorld
to check for any memory issues.
Several memory leaks are reported and I wondered if you also have this issue.
While trying to build a c++ class with g++ with swig for using it in python, I get the compiling error mentioned above. Is there an issue in the implementation?
running build_ext building '_CommunicationViaNNG' extension swigging CommunicationViaNNG.i to CommunicationViaNNG_wrap.cpp swig -python -c++ -o CommunicationViaNNG_wrap.cpp CommunicationViaNNG.i creating build creating build/temp.linux-x86_64-3.6 g++ -DNDEBUG -g -fwrapv -O2 -Wall -g -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -fPIC -Isrc -I/usr/include/python3.6m -c CommunicationViaNNG_wrap.cpp -o build/temp.linux-x86_64-3.6/CommunicationViaNNG_wrap.o -I/home/user1/Documents/extLibs -lnng -lpthread CommunicationViaNNG_wrap.cpp: In function ‘PyObject* _wrap_CommIF_socket_set(PyObject*, PyObject*)’: CommunicationViaNNG_wrap.cpp:2962:15: error: use of deleted function ‘nng::socket& nng::socket::operator=(const nng::socket&)’ arg2 = *temp; ^~~~ In file included from /home/user1/Documents/extLibs/nngpp/nngpp.h:3:0, from src/CommunicationViaNNG.h:1, from CommunicationViaNNG_wrap.cpp:2774: /home/user1/Documents/extLibs/nngpp/socket.h:19:10: note: declared here socket& operator=( const socket& rhs ) = delete; ^~~~~~~~ CommunicationViaNNG_wrap.cpp:2966:30: error: use of deleted function ‘nng::socket& nng::socket::operator=(const nng::socket&)’ if (arg1) (arg1)->socket = arg2; ^~~~ In file included from /home/user1/Documents/extLibs/nngpp/nngpp.h:3:0, from src/CommunicationViaNNG.h:1, from CommunicationViaNNG_wrap.cpp:2774: /home/user1/Documents/extLibs/nngpp/socket.h:19:10: note: declared here socket& operator=( const socket& rhs ) = delete; ^~~~~~~~ CommunicationViaNNG_wrap.cpp: In function ‘PyObject* _wrap_CommIF_socket_get(PyObject*, PyObject*)’: CommunicationViaNNG_wrap.cpp:2989:28: error: use of deleted function ‘nng::socket& nng::socket::operator=(const nng::socket&)’ result = ((arg1)->socket); ^ In file included from /home/user1/Documents/extLibs/nngpp/nngpp.h:3:0, from src/CommunicationViaNNG.h:1, from CommunicationViaNNG_wrap.cpp:2774: /home/user1/Documents/extLibs/nngpp/socket.h:19:10: note: declared here socket& operator=( const socket& rhs ) = delete; ^~~~~~~~ CommunicationViaNNG_wrap.cpp:2990:92: error: use of deleted function ‘nng::socket::socket(const nng::socket&)’ ointerObj((new nng::socket(static_cast< const nng::socket& >(result))), SWIGTYPE_p_nng__socket, SWIG_POINTER_OWN | 0 ); ^ CommunicationViaNNG_wrap.cpp:1088:89: note: in definition of macro ‘SWIG_NewPointerObj’ terObj(ptr, type, flags) SWIG_Python_NewPointerObj(NULL, ptr, type, flags) ^~~ In file included from /home/user1/Documents/extLibs/nngpp/nngpp.h:3:0, from src/CommunicationViaNNG.h:1, from CommunicationViaNNG_wrap.cpp:2774: /home/user1/Documents/extLibs/nngpp/socket.h:13:2: note: declared here socket( const socket& rhs ) = delete; ^~~~~~ error: command 'g++' failed with exit status 1
I am getting the following error:
\include\nngpp\dialer_view.h(38): error C3861: 'nng_dialer_set': identifier not found
I can find this identifier with fulltext search neither in the nng git nor in nngpp.
Am I missing something or this just so much WiP that it is supposed to be broken?
Cheers
~Y.
I'm doing a stress test with a pairv1 protocol and the socket is closing around 61000 messages with 1000 msg/second.
Even if i slow it down (500msg/sec), it drops the connection too around 61000 messages in the dialer side.
I've found a similar problem in the closed issues, but i'm following the right instructions and still having the problem.
The connection code:
nng::socket sockx = nng::pair::v1::open();
sock = std::make_shared<nng::socket>( sockx.release() );
sock->dial(URL.c_str());
The rest, is just as it supose to be and i've create a repository with most part of the code:
https://github.com/amunhoz/nng_application
Another important thing, it is a node addon project.
With using socket.listen(addr) or socket.dial(addr) is there a way to un-listen / un-dial or shutdown an endpoint without closing the socket?
Hello. Can I send and receive a structure?
Something like this:
Structure in both apps:
struct Data_t{
int code;
char* msg;
};
First process:
Data_t data{5, "ok"};
socket.send(data);
...
Second process:
Data_t data;
data = socket.recv();
int code = data.code;
...
I am getting a compilation error related to the use of catch2 v2.12.2 in test/http_client.cpp (GCC 10.1)
In file included from /var/cache/makepkg/nngpp-git/src/nngpp/test/http_client.cpp:1:
/usr/include/catch2/catch.hpp: In instantiation of ‘std::string Catch::rangeToString(const Range&) [with Range = nng::aio; std::string = std::__cxx11::basic_string<char>]’:
/usr/include/catch2/catch.hpp:2046:33: required from ‘static std::string Catch::StringMaker<R, typename std::enable_if<(Catch::is_range<T>::value && (! Catch::Detail::IsStreamInsertable<T>::value))>::type>::convert(const R&) [with R = nng::aio; std::string = std::__cxx11::basic_string<char>]’
/usr/include/catch2/catch.hpp:1649:121: required from ‘std::string Catch::Detail::stringify(const T&) [with T = nng::aio; std::string = std::__cxx11::basic_string<char>]’
/usr/include/catch2/catch.hpp:2308:43: required from ‘void Catch::UnaryExpr<LhsT>::streamReconstructedExpression(std::ostream&) const [with LhsT = const nng::aio&; std::ostream = std::basic_ostream<char>]’
/usr/include/catch2/catch.hpp:2307:14: required from here
/usr/include/catch2/catch.hpp:2023:67: error: no matching function for call to ‘end(const nng::aio&)’
2023 | return ::Catch::Detail::rangeToString( begin( range ), end( range ) );
| ~~~^~~~~~~~~
In file included from /usr/include/c++/10.1.0/string:54,
from /usr/include/catch2/catch.hpp:481,
from /var/cache/makepkg/nngpp-git/src/nngpp/test/http_client.cpp:1:
/usr/include/c++/10.1.0/bits/range_access.h:110:37: note: candidate: ‘template<class _Tp> const _Tp* std::end(const std::valarray<_Tp>&)’
110 | template<typename _Tp> const _Tp* end(const valarray<_Tp>&);
| ^~~
/usr/include/c++/10.1.0/bits/range_access.h:110:37: note: template argument deduction/substitution failed:
In file included from /var/cache/makepkg/nngpp-git/src/nngpp/test/http_client.cpp:1:
/usr/include/catch2/catch.hpp:2023:67: note: ‘const nng::aio’ is not derived from ‘const std::valarray<_Tp>’
2023 | return ::Catch::Detail::rangeToString( begin( range ), end( range ) );
| ~~~^~~~~~~~~
In file included from /usr/include/c++/10.1.0/string:54,
from /usr/include/catch2/catch.hpp:481,
from /var/cache/makepkg/nngpp-git/src/nngpp/test/http_client.cpp:1:
/usr/include/c++/10.1.0/bits/range_access.h:109:31: note: candidate: ‘template<class _Tp> _Tp* std::end(std::valarray<_Tp>&)’
109 | template<typename _Tp> _Tp* end(valarray<_Tp>&);
| ^~~
/usr/include/c++/10.1.0/bits/range_access.h:109:31: note: template argument deduction/substitution failed:
In file included from /var/cache/makepkg/nngpp-git/src/nngpp/test/http_client.cpp:1:
/usr/include/catch2/catch.hpp:2023:67: note: types ‘std::valarray<_Tp>’ and ‘const nng::aio’ have incompatible cv-qualifiers
2023 | return ::Catch::Detail::rangeToString( begin( range ), end( range ) );
| ~~~^~~~~~~~~
In file included from /usr/include/c++/10.1.0/string:54,
from /usr/include/catch2/catch.hpp:481,
from /var/cache/makepkg/nngpp-git/src/nngpp/test/http_client.cpp:1:
/usr/include/c++/10.1.0/bits/range_access.h:100:5: note: candidate: ‘template<class _Tp, long unsigned int _Nm> constexpr _Tp* std::end(_Tp (&)[_Nm])’
100 | end(_Tp (&__arr)[_Nm])
| ^~~
/usr/include/c++/10.1.0/bits/range_access.h:100:5: note: template argument deduction/substitution failed:
In file included from /var/cache/makepkg/nngpp-git/src/nngpp/test/http_client.cpp:1:
/usr/include/catch2/catch.hpp:2023:67: note: mismatched types ‘_Tp [_Nm]’ and ‘const nng::aio’
2023 | return ::Catch::Detail::rangeToString( begin( range ), end( range ) );
| ~~~^~~~~~~~~
In file included from /usr/include/c++/10.1.0/string:54,
from /usr/include/catch2/catch.hpp:481,
from /var/cache/makepkg/nngpp-git/src/nngpp/test/http_client.cpp:1:
/usr/include/c++/10.1.0/bits/range_access.h:81:5: note: candidate: ‘template<class _Container> constexpr decltype (__cont.end()) std::end(const _Container&)’
81 | end(const _Container& __cont) -> decltype(__cont.end())
| ^~~
/usr/include/c++/10.1.0/bits/range_access.h:81:5: note: template argument deduction/substitution failed:
/usr/include/c++/10.1.0/bits/range_access.h: In substitution of ‘template<class _Container> constexpr decltype (__cont.end()) std::end(const _Container&) [with _Container = nng::aio]’:
/usr/include/catch2/catch.hpp:2023:67: required from ‘std::string Catch::rangeToString(const Range&) [with Range = nng::aio; std::string = std::__cxx11::basic_string<char>]’
/usr/include/catch2/catch.hpp:2046:33: required from ‘static std::string Catch::StringMaker<R, typename std::enable_if<(Catch::is_range<T>::value && (! Catch::Detail::IsStreamInsertable<T>::value))>::type>::convert(const R&) [with R = nng::aio; std::string = std::__cxx11::basic_string<char>]’
/usr/include/catch2/catch.hpp:1649:121: required from ‘std::string Catch::Detail::stringify(const T&) [with T = nng::aio; std::string = std::__cxx11::basic_string<char>]’
/usr/include/catch2/catch.hpp:2308:43: required from ‘void Catch::UnaryExpr<LhsT>::streamReconstructedExpression(std::ostream&) const [with LhsT = const nng::aio&; std::ostream = std::basic_ostream<char>]’
/usr/include/catch2/catch.hpp:2307:14: required from here
/usr/include/c++/10.1.0/bits/range_access.h:81:54: error: ‘const struct nng::aio’ has no member named ‘end’
81 | end(const _Container& __cont) -> decltype(__cont.end())
| ~~~~~~~^~~
/usr/include/catch2/catch.hpp: In instantiation of ‘std::string Catch::rangeToString(const Range&) [with Range = nng::aio; std::string = std::__cxx11::basic_string<char>]’:
/usr/include/catch2/catch.hpp:2046:33: required from ‘static std::string Catch::StringMaker<R, typename std::enable_if<(Catch::is_range<T>::value && (! Catch::Detail::IsStreamInsertable<T>::value))>::type>::convert(const R&) [with R = nng::aio; std::string = std::__cxx11::basic_string<char>]’
/usr/include/catch2/catch.hpp:1649:121: required from ‘std::string Catch::Detail::stringify(const T&) [with T = nng::aio; std::string = std::__cxx11::basic_string<char>]’
/usr/include/catch2/catch.hpp:2308:43: required from ‘void Catch::UnaryExpr<LhsT>::streamReconstructedExpression(std::ostream&) const [with LhsT = const nng::aio&; std::ostream = std::basic_ostream<char>]’
/usr/include/catch2/catch.hpp:2307:14: required from here
/usr/include/c++/10.1.0/bits/range_access.h:71:5: note: candidate: ‘template<class _Container> constexpr decltype (__cont.end()) std::end(_Container&)’
71 | end(_Container& __cont) -> decltype(__cont.end())
| ^~~
/usr/include/c++/10.1.0/bits/range_access.h:71:5: note: template argument deduction/substitution failed:
/usr/include/c++/10.1.0/bits/range_access.h: In substitution of ‘template<class _Container> constexpr decltype (__cont.end()) std::end(_Container&) [with _Container = const nng::aio]’:
/usr/include/catch2/catch.hpp:2023:67: required from ‘std::string Catch::rangeToString(const Range&) [with Range = nng::aio; std::string = std::__cxx11::basic_string<char>]’
/usr/include/catch2/catch.hpp:2046:33: required from ‘static std::string Catch::StringMaker<R, typename std::enable_if<(Catch::is_range<T>::value && (! Catch::Detail::IsStreamInsertable<T>::value))>::type>::convert(const R&) [with R = nng::aio; std::string = std::__cxx11::basic_string<char>]’
/usr/include/catch2/catch.hpp:1649:121: required from ‘std::string Catch::Detail::stringify(const T&) [with T = nng::aio; std::string = std::__cxx11::basic_string<char>]’
/usr/include/catch2/catch.hpp:2308:43: required from ‘void Catch::UnaryExpr<LhsT>::streamReconstructedExpression(std::ostream&) const [with LhsT = const nng::aio&; std::ostream = std::basic_ostream<char>]’
/usr/include/catch2/catch.hpp:2307:14: required from here
/usr/include/c++/10.1.0/bits/range_access.h:71:48: error: ‘const struct nng::aio’ has no member named ‘end’
71 | end(_Container& __cont) -> decltype(__cont.end())
| ~~~~~~~^~~
In file included from /usr/include/c++/10.1.0/bits/range_access.h:36,
from /usr/include/c++/10.1.0/string:54,
from /usr/include/catch2/catch.hpp:481,
from /var/cache/makepkg/nngpp-git/src/nngpp/test/http_client.cpp:1:
/usr/include/catch2/catch.hpp: In instantiation of ‘std::string Catch::rangeToString(const Range&) [with Range = nng::aio; std::string = std::__cxx11::basic_string<char>]’:
/usr/include/catch2/catch.hpp:2046:33: required from ‘static std::string Catch::StringMaker<R, typename std::enable_if<(Catch::is_range<T>::value && (! Catch::Detail::IsStreamInsertable<T>::value))>::type>::convert(const R&) [with R = nng::aio; std::string = std::__cxx11::basic_string<char>]’
/usr/include/catch2/catch.hpp:1649:121: required from ‘std::string Catch::Detail::stringify(const T&) [with T = nng::aio; std::string = std::__cxx11::basic_string<char>]’
/usr/include/catch2/catch.hpp:2308:43: required from ‘void Catch::UnaryExpr<LhsT>::streamReconstructedExpression(std::ostream&) const [with LhsT = const nng::aio&; std::ostream = std::basic_ostream<char>]’
/usr/include/catch2/catch.hpp:2307:14: required from here
/usr/include/c++/10.1.0/initializer_list:101:5: note: candidate: ‘template<class _Tp> constexpr const _Tp* std::end(std::initializer_list<_Tp>)’
101 | end(initializer_list<_Tp> __ils) noexcept
| ^~~
/usr/include/c++/10.1.0/initializer_list:101:5: note: template argument deduction/substitution failed:
In file included from /var/cache/makepkg/nngpp-git/src/nngpp/test/http_client.cpp:1:
/usr/include/catch2/catch.hpp:2023:67: note: ‘nng::aio’ is not derived from ‘std::initializer_list<_Tp>’
2023 | return ::Catch::Detail::rangeToString( begin( range ), end( range ) );
| ~~~^~~~~~~~~
Hello,
the last release of nngpp is 1.1.1, but nng itself is already at 1.2.3, with 1.3.0 just around the corner. So how compatible is nngpp with current nng? Right now, I'm using nngpp-1.1.1 with nng-1.1.1, and I would like to upgrade nng without too much breakage.
Thanks.
Not really an issue, just a question :)
If I do:
socket.listen(somePath);
...
socket.listen(newPath);
do I need to do anything to release the listener (eg. socket = nng::something::open
) or is it ok to directly call listen
the second time?
Why are buffer and view based on cstring instead of std::string?
I am thinking about wrapping or refactoring them, would it be good?
Thanks for the advice!
I needed to wrap pre-allocated memory into a buffer which i did with nng::view( T* d, size_t s )
because nng::buffer( T* d, size_t s)
will free the pointer to d so i will get double free. But unfortunately nng::socket_view::recv
has no overload for nng::view
only for nng::buffer
.
Hello! Can someone please explain the steps to link the library without copying the folder into an actual project.
mkdir build
cd build
cmake ..
make
make install
then I used the following in my CMakeLists.txt
cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
project(comm)
find_package(nngpp CONFIG REQUIRED)
add_executable(server src/server.cpp)
target_link_libraries(server nngpp)
I was presented with the following:
fatal error: 'nngpp/nngpp.h' file not found
#include <nngpp/nngpp.h>
^~~~~~~~~~~~~~~
1 error generated.
make[2]: *** [CMakeFiles/server.dir/src/tfo-server.cpp.o] Error 1
make[1]: *** [CMakeFiles/server.dir/all] Error 2
make: *** [all] Error 2
When I try to call aio.stop() at the end of the program, it causes the program to crash
(Lodging an issue for this; I might be inclined to develop a pull request.)
C++11 introduces an error_code class that can accommodate both POSIX standard error codes and alternative collections of error codes such as NNG's. An error_code includes an integer value (0 for no error) and an error category which can be either the C++/POSIX one or some custom category. nngpp would benefit from implementing a custom error category.
https://en.cppreference.com/w/cpp/error/error_category
Implementations of std::error_category have a few responsibilities: Categorizing error codes, providing string representations, and mapping platform-dependent codes to platform-agnostic ones (including standard C++/POSIX error codes). These functions serve to make codebases more consistent and integrable; for example, libasio uses std::error_code extensively.
I recommend making nng::error convertible to std::error_code
and/or adding a method for doing so to nng::exception
.
The POSIX error codes supported by C++11 are listed here: https://en.cppreference.com/w/cpp/error/errc
The following codes have no direct mapping to a C++/POSIX equivalent.
NNG CODE | possible C++ mapping |
---|---|
ECLOSED | |
ESTATE | |
EUNREACHABLE, EADDRINVAL | address_not_available |
ENOFILES | |
EREADONLY / EWRITEONLY | |
ECRYPTO / EPEERAUTH | |
ENOARG / EAMBIGUOUS / EBADTYPE | |
ECONNSHUT | connection_aborted |
EINTERNAL | |
ESYSERR | |
ETRANERR |
These codes would need to be either lossily mapped to C++ codes or implemented as an NNG-specific error_condition
. It would be somewhat advantageous to assign them values that don't conflict with the standard C++ ones.
Not sure what tools' versions are relevant here, but on Ubuntu 16 I had to make the following changes in order to build the demos:
add two lines to CmakeLists.txt
:
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
Add #include <utility>
to source files that use std::move
The nng::close_all()
function calls the nng_closeall()
from nng
which is deprecated:
where it is called:
Line 39 in 8da8c02
original function which is now deprecated:
https://github.com/nanomsg/nng/blob/a6de76c0b1e08ceba5c3e47dd1107f1a09490b0d/include/nng/nng.h#L1325
As a result, compiling code that includes nngpp/core.h
generates many deprecation warnings that could result in compilation errors the day when nng
will completely remove the nng_closeall()
function from their code base.
"undefined symblol nng_close"
"undefined symblol nng_dial"
"undefined symblol nng_free"
...
VS2017 in both master and 1.1.1
nng built with VS2017 tested tag 1.1.1 and master
How can that be resolved?
nng 1.3.0
protocol pair:v1
gcc version 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04)
code:
sockx->set_opt_ms(nng::to_name(nng::option::reconnect_time_min), (nng_duration)1000);
throws
test: malloc.c:2401: sysmalloc: Assertion `(old_top == initial_top (av) && old_size == 0) || ((unsigned long) (old_size) >= MINSIZE && prev_inuse (old_top) && ((unsigned long) old_end & (pagesize - 1)) == 0)' failed.
Aborted (core dumped)
The error log:
xxxx/libs/nngpp/include/nngpp/stat_view.h: In member function 'nng::stat_view nng::stat_view::find(const char*) const':
xxxx/libs/nngpp/include/nngpp/stat_view.h:86:31: error: 'nng_stat_find' was not declared in this scope
return nng_stat_find(s, name);
^
xxxx/libs/nngpp/include/nngpp/stat_view.h: In member function 'nng::stat_view nng::stat_view::find(nng::socket_view) const':
xxxx/libs/nngpp/include/nngpp/stat_view.h:90:46: error: 'nng_stat_find_socket' was not declared in this scope
return nng_stat_find_socket(s, socket.get());
^
xxxx/libs/nngpp/include/nngpp/stat_view.h: In member function 'nng::stat_view nng::stat_view::find(nng::dialer_view) const':
xxxx/libs/nngpp/include/nngpp/stat_view.h:94:46: error: 'nng_stat_find_dialer' was not declared in this scope
return nng_stat_find_dialer(s, dialer.get());
^
xxxx/libs/nngpp/include/nngpp/stat_view.h: In member function 'nng::stat_view nng::stat_view::find(nng::listener_view) const':
xxxx/libs/nngpp/include/nngpp/stat_view.h:98:50: error: 'nng_stat_find_listener' was not declared in this scope
return nng_stat_find_listener(s, listener.get());
Comment out these line can solve the problem, but I think that is not a good idea
While testing a req-rep minimal setup with wss://, no message is sent or received when using IPV6 addresses. With IPV4 ones, or with 'localhost', the client/server messaging is straightforward. Firewall is off on the host.
The attached file may demonstrate it.
I don't know if it's the right place to seek help resolving this. I'm posting here because I'm using nngpp, and not the C interface directly.
Regards.
While trying to use nngpp with a pub/sub protocol, I spent hours trying to diagnose why I never received anything, while the exact same sequence using nng calls worked. The problem was this:
socket.set_opt( NNG_OPT_SUB_SUBSCRIBE, "" );
The problem is that the type translation results in this becoming:
nng_setopt( socket, NNG_OPT_SUB_SUBSCRIBE, "", 1 );
as a one-byte buffer (containing \0). To succeed, the fourth parameter needs to be 0. This can be force by using
socket.set_opt( NNG_OPT_SUB_SUBSCRIBE, nng:view("",0) );
but that seems to be a hack.
I cannot think of any situations where the zero-terminator should be included in a set_opt string.
I'm having some problems with building the code on macOS. I've installed the NNG library through HomeBrew and I have it located on this path: /usr/local/Cellar/nng/1.1.1
. Here's what I've changed in the makefile
:
NNG_INC = /usr/local/Cellar/nng/1.1.1/include/
NNG_LNK = -L/usr/local/Cellar/nng/1.1.1/lib/ -lnng -lmbedtls -lmbedx509 -lmbedcrypto
And here's the output after I run make
:
Project/nngpp [master*] » make
g++ -I/Users/klemen/Project/nngpp/include -I/usr/local/Cellar/nng/1.1.1/include/ -I -Wall -Wextra -std=c++17 -march=native -O3 -DNDEBUG -Wno-unused-parameter -o /Users/klemen/Project/nngpp/bin/demo/async/client /Users/klemen/Project/nngpp/demo/async/client.cpp -L/usr/local/Cellar/nng/1.1.1/lib/ -lnng -lmbedtls -lmbedx509 -lmbedcrypto -lpthread
In file included from /Users/klemen/Project/nngpp/demo/async/client.cpp:6:
In file included from /Users/klemen/Project/nngpp/include/nngpp/nngpp.h:11:
In file included from /Users/klemen/Project/nngpp/include/nngpp/stream/dialer.h:3:
/Users/klemen/Project/nngpp/include/nngpp/stream/dialer_view.h:9:2: error: unknown type name 'nng_stream_dialer'
nng_stream_dialer* d = nullptr;
^
/Users/klemen/Project/nngpp/include/nngpp/stream/dialer_view.h:14:15: error: unknown type name 'nng_stream_dialer'
dialer_view( nng_stream_dialer* d ) noexcept : d(d) {}
^
/Users/klemen/Project/nngpp/include/nngpp/stream/dialer_view.h:16:2: error: unknown type name 'nng_stream_dialer'
nng_stream_dialer* get() const noexcept {
^
/Users/klemen/Project/nngpp/include/nngpp/stream/dialer_view.h:20:2: error: unknown type name 'nng_stream_dialer'
nng_stream_dialer* operator->() const noexcept {
^
In file included from /Users/klemen/Project/nngpp/demo/async/client.cpp:6:
In file included from /Users/klemen/Project/nngpp/include/nngpp/nngpp.h:11:
/Users/klemen/Project/nngpp/include/nngpp/stream/dialer.h:12:19: error: unknown type name 'nng_stream_dialer'
explicit dialer( nng_stream_dialer* d ) noexcept : dialer_view(d) {}
^
/Users/klemen/Project/nngpp/include/nngpp/stream/dialer.h:49:2: error: unknown type name 'nng_stream_dialer'
nng_stream_dialer* release() noexcept {
^
In file included from /Users/klemen/Project/nngpp/demo/async/client.cpp:6:
In file included from /Users/klemen/Project/nngpp/include/nngpp/nngpp.h:12:
In file included from /Users/klemen/Project/nngpp/include/nngpp/stream/listener.h:3:
/Users/klemen/Project/nngpp/include/nngpp/stream/listener_view.h:9:2: error: unknown type name 'nng_stream_listener'
nng_stream_listener* d = nullptr;
^
/Users/klemen/Project/nngpp/include/nngpp/stream/listener_view.h:14:17: error: unknown type name 'nng_stream_listener'
listener_view( nng_stream_listener* d ) noexcept : d(d) {}
^
/Users/klemen/Project/nngpp/include/nngpp/stream/listener_view.h:16:2: error: unknown type name 'nng_stream_listener'
nng_stream_listener* get() const noexcept {
^
/Users/klemen/Project/nngpp/include/nngpp/stream/listener_view.h:20:2: error: unknown type name 'nng_stream_listener'
nng_stream_listener* operator->() const noexcept {
^
In file included from /Users/klemen/Project/nngpp/demo/async/client.cpp:6:
In file included from /Users/klemen/Project/nngpp/include/nngpp/nngpp.h:12:
/Users/klemen/Project/nngpp/include/nngpp/stream/listener.h:12:21: error: unknown type name 'nng_stream_listener'
explicit listener( nng_stream_listener* d ) noexcept : listener_view(d) {}
^
/Users/klemen/Project/nngpp/include/nngpp/stream/listener.h:49:2: error: unknown type name 'nng_stream_listener'
nng_stream_listener* release() noexcept {
^
In file included from /Users/klemen/Project/nngpp/demo/async/client.cpp:6:
In file included from /Users/klemen/Project/nngpp/include/nngpp/nngpp.h:13:
In file included from /Users/klemen/Project/nngpp/include/nngpp/stream/stream.h:3:
/Users/klemen/Project/nngpp/include/nngpp/stream/stream_view.h:9:2: error: unknown type name 'nng_stream'; did you mean 'nng_stat'?
nng_stream* s = nullptr;
^~~~~~~~~~
nng_stat
/usr/local/Cellar/nng/1.1.1/include/nng/nng.h:95:25: note: 'nng_stat' declared here
typedef struct nng_stat nng_stat;
^
In file included from /Users/klemen/Project/nngpp/demo/async/client.cpp:6:
In file included from /Users/klemen/Project/nngpp/include/nngpp/nngpp.h:13:
In file included from /Users/klemen/Project/nngpp/include/nngpp/stream/stream.h:3:
/Users/klemen/Project/nngpp/include/nngpp/stream/stream_view.h:14:15: error: unknown type name 'nng_stream'; did you mean 'nng_stat'?
stream_view( nng_stream* s ) noexcept : s(s) {}
^~~~~~~~~~
nng_stat
/usr/local/Cellar/nng/1.1.1/include/nng/nng.h:95:25: note: 'nng_stat' declared here
typedef struct nng_stat nng_stat;
^
In file included from /Users/klemen/Project/nngpp/demo/async/client.cpp:6:
In file included from /Users/klemen/Project/nngpp/include/nngpp/nngpp.h:13:
In file included from /Users/klemen/Project/nngpp/include/nngpp/stream/stream.h:3:
/Users/klemen/Project/nngpp/include/nngpp/stream/stream_view.h:16:2: error: unknown type name 'nng_stream'; did you mean 'nng_stat'?
nng_stream* get() const noexcept {
^~~~~~~~~~
nng_stat
/usr/local/Cellar/nng/1.1.1/include/nng/nng.h:95:25: note: 'nng_stat' declared here
typedef struct nng_stat nng_stat;
^
In file included from /Users/klemen/Project/nngpp/demo/async/client.cpp:6:
In file included from /Users/klemen/Project/nngpp/include/nngpp/nngpp.h:13:
In file included from /Users/klemen/Project/nngpp/include/nngpp/stream/stream.h:3:
/Users/klemen/Project/nngpp/include/nngpp/stream/stream_view.h:20:2: error: unknown type name 'nng_stream'; did you mean 'nng_stat'?
nng_stream* operator->() const noexcept {
^~~~~~~~~~
nng_stat
/usr/local/Cellar/nng/1.1.1/include/nng/nng.h:95:25: note: 'nng_stat' declared here
typedef struct nng_stat nng_stat;
^
In file included from /Users/klemen/Project/nngpp/demo/async/client.cpp:6:
In file included from /Users/klemen/Project/nngpp/include/nngpp/nngpp.h:13:
In file included from /Users/klemen/Project/nngpp/include/nngpp/stream/stream.h:3:
/Users/klemen/Project/nngpp/include/nngpp/stream/stream_view.h:29:3: error: use of undeclared identifier 'nng_stream_close'
nng_stream_close(s);
^
/Users/klemen/Project/nngpp/include/nngpp/stream/stream_view.h:33:3: error: use of undeclared identifier 'nng_stream_send'; did you mean 'nng_ctx_send'?
nng_stream_send(s,a.get());
^~~~~~~~~~~~~~~
nng_ctx_send
/usr/local/Cellar/nng/1.1.1/include/nng/nng.h:436:15: note: 'nng_ctx_send' declared here
NNG_DECL void nng_ctx_send(nng_ctx, nng_aio *);
^
In file included from /Users/klemen/Project/nngpp/demo/async/client.cpp:6:
In file included from /Users/klemen/Project/nngpp/include/nngpp/nngpp.h:13:
In file included from /Users/klemen/Project/nngpp/include/nngpp/stream/stream.h:3:
/Users/klemen/Project/nngpp/include/nngpp/stream/stream_view.h:33:19: error: no viable conversion from 'nng_stat *const' to 'nng_ctx' (aka 'nng_ctx_s')
nng_stream_send(s,a.get());
^
/usr/local/Cellar/nng/1.1.1/include/nng/nng.h:73:16: note: candidate constructor (the implicit copy constructor) not viable: cannot convert argument of incomplete type 'nng_stat *const' to
'const nng_ctx_s &' for 1st argument
typedef struct nng_ctx_s {
^
/usr/local/Cellar/nng/1.1.1/include/nng/nng.h:73:16: note: candidate constructor (the implicit move constructor) not viable: cannot convert argument of incomplete type 'nng_stat *const' to 'nng_ctx_s &&'
for 1st argument
/usr/local/Cellar/nng/1.1.1/include/nng/nng.h:436:35: note: passing argument to parameter here
NNG_DECL void nng_ctx_send(nng_ctx, nng_aio *);
^
fatal error: too many errors emitted, stopping now [-ferror-limit=]
20 errors generated.
make: *** [/Users/klemen/Project/nngpp/bin/demo/async/client] Error 1
Any ideas what I'm doing wrong?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.