Skip to content

Commit

Permalink
open nng socket types, pass them to js as node buffers
Browse files Browse the repository at this point in the history
  • Loading branch information
reqshark committed Feb 19, 2019
1 parent 9e928ea commit 787bd7d
Show file tree
Hide file tree
Showing 10 changed files with 287 additions and 133 deletions.
4 changes: 4 additions & 0 deletions COPYING
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
Copyright (c) 2019 Bent Cardan <[email protected]>
Copyright (c) 2019 Garrett D'Amore <[email protected]>
Copyright (c) 2018 Staysail Systems, Inc. <[email protected]>
Copyright (c) 2018 Capitar IT Group BV <[email protected]>

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"),
Expand Down
239 changes: 120 additions & 119 deletions binding.cc
Original file line number Diff line number Diff line change
@@ -1,36 +1,40 @@
/*
Copyright (c) 2019 Bent Cardan <[email protected]>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom
the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE.
*/

#include <nng/nng.h>
#include <nng/protocol/bus0/bus.h>
#include <nng/protocol/pair0/pair.h>
#include <nng/protocol/pair1/pair.h>
#include <nng/protocol/pubsub0/pub.h>
#include <nng/protocol/pipeline0/pull.h>
#include <nng/protocol/pipeline0/push.h>
#include <nng/protocol/reqrep0/rep.h>
#include <nng/protocol/reqrep0/req.h>
#include <nng/protocol/survey0/respond.h>
#include <nng/protocol/pubsub0/sub.h>
#include <nng/protocol/survey0/survey.h>

#include "timer.h"
#include "nan.h"

#define CLIENT "client"
#define SERVER "server"
#define DATECMD 1

#define PUT64(ptr, u) \
do { \
(ptr)[0] = (uint8_t)(((uint64_t)(u)) >> 56); \
(ptr)[1] = (uint8_t)(((uint64_t)(u)) >> 48); \
(ptr)[2] = (uint8_t)(((uint64_t)(u)) >> 40); \
(ptr)[3] = (uint8_t)(((uint64_t)(u)) >> 32); \
(ptr)[4] = (uint8_t)(((uint64_t)(u)) >> 24); \
(ptr)[5] = (uint8_t)(((uint64_t)(u)) >> 16); \
(ptr)[6] = (uint8_t)(((uint64_t)(u)) >> 8); \
(ptr)[7] = (uint8_t)((uint64_t)(u)); \
} while (0)

#define GET64(ptr, v) \
v = (((uint64_t)((uint8_t)(ptr)[0])) << 56) + \
(((uint64_t)((uint8_t)(ptr)[1])) << 48) + \
(((uint64_t)((uint8_t)(ptr)[2])) << 40) + \
(((uint64_t)((uint8_t)(ptr)[3])) << 32) + \
(((uint64_t)((uint8_t)(ptr)[4])) << 24) + \
(((uint64_t)((uint8_t)(ptr)[5])) << 16) + \
(((uint64_t)((uint8_t)(ptr)[6])) << 8) + \
(((uint64_t)(uint8_t)(ptr)[7]))

#include "ref.h"

using v8::FunctionTemplate;
using v8::Function;
Expand All @@ -40,6 +44,7 @@ using v8::String;
using v8::Object;
using v8::Value;
using v8::Local;

using Nan::HandleScope;
using Nan::MaybeLocal;
using Nan::NewBuffer;
Expand All @@ -49,107 +54,92 @@ using Nan::Set;
using Nan::New;
using Nan::To;

void
fatal(const char *func, int rv)
{
fprintf(stderr, "%s: %s\n", func, nng_strerror(rv));
exit(1);
//NAN_METHOD(aiosock1){
// const char *addr = "inproc://aio";
// printf("aio test\n");
// nng_socket s1;
// nng_socket s2;
// nng_aio * txaio;
// nng_aio * rxaio;
// int txdone = 0;
// int rxdone = 0;
// nng_msg * m;
// nng_pair1_open(&s1);
// nng_pair1_open(&s2);
// nng_listen(s1, addr, NULL, 0);
// nng_aio *saio;
// nng_aio_alloc(&saio, sleepdone, &end));
// return;
//}

NAN_METHOD(bus_open) {
nng_socket s;
nng_bus0_open(&s); //nng_bus0_open_raw
info.GetReturnValue().Set(WrapPointer(&s, sizeof(nng_socket)));
}

void
showdate(time_t now)
{
struct tm *info = localtime(&now);
printf("%s", asctime(info));
NAN_METHOD(pair0_open) {
nng_socket s;
nng_pair0_open(&s); //nng_pair0_open_raw
info.GetReturnValue().Set(WrapPointer(&s, sizeof(nng_socket)));
}

int
server(const char *url)
{
nng_socket sock;
int rv;

if ((rv = nng_rep0_open(&sock)) != 0) {
fatal("nng_rep0_open", rv);
}
if ((rv = nng_listen(sock, url, NULL, 0)) != 0) {
fatal("nng_listen", rv);
}
for (;;) {
char * buf = NULL;
size_t sz;
uint64_t val;
if ((rv = nng_recv(sock, &buf, &sz, NNG_FLAG_ALLOC)) != 0) {
fatal("nng_recv", rv);
}
if ((sz == sizeof(uint64_t)) &&
((GET64(buf, val)) == DATECMD)) {
time_t now;
printf("SERVER: RECEIVED DATE REQUEST\n");
now = time(&now);
printf("SERVER: SENDING DATE: ");
showdate(now);

// Reuse the buffer. We know it is big enough.
PUT64(buf, (uint64_t) now);
rv = nng_send(sock, buf, sz, NNG_FLAG_ALLOC);
if (rv != 0) {
fatal("nng_send", rv);
}
continue;
}
// Unrecognized command, so toss the buffer.
nng_free(buf, sz);
}
//NNG_OPT_PAIR1_POLY
//NNG_OPT_MAXTTL
NAN_METHOD(pair1_open) {
nng_socket s;
nng_pair1_open(&s); //nng_pair1_open_raw
info.GetReturnValue().Set(WrapPointer(&s, sizeof(nng_socket)));
}


int
client(const char *url)
{
nng_socket sock;
int rv;
size_t sz;
char * buf = NULL;
uint8_t cmd[sizeof(uint64_t)];

PUT64(cmd, DATECMD);

if ((rv = nng_req0_open(&sock)) != 0) {
fatal("nng_socket", rv);
}
if ((rv = nng_dial(sock, url, NULL, 0)) != 0) {
fatal("nng_dial", rv);
}
printf("CLIENT: SENDING DATE REQUEST\n");
if ((rv = nng_send(sock, cmd, sizeof(cmd), 0)) != 0) {
fatal("nng_send", rv);
}
if ((rv = nng_recv(sock, &buf, &sz, NNG_FLAG_ALLOC)) != 0) {
fatal("nng_recv", rv);
}

if (sz == sizeof(uint64_t)) {
uint64_t now;
GET64(buf, now);
printf("CLIENT: RECEIVED DATE: ");
showdate((time_t) now);
} else {
printf("CLIENT: GOT WRONG SIZE!\n");
}

// This assumes that buf is ASCIIZ (zero terminated).
nng_free(buf, sz);
nng_close(sock);
return (0);

NAN_METHOD(pub_open) {
nng_socket s;
nng_pub0_open(&s); //nng_pub0_open_raw
info.GetReturnValue().Set(WrapPointer(&s, sizeof(nng_socket)));
}

NAN_METHOD(pull_open) {
nng_socket s;
nng_pull0_open(&s); //nng_pull0_open_raw
info.GetReturnValue().Set(WrapPointer(&s, sizeof(nng_socket)));
}

NAN_METHOD(push_open) {
nng_socket s;
nng_push0_open(&s); //nng_push0_open_raw
info.GetReturnValue().Set(WrapPointer(&s, sizeof(nng_socket)));
}

NAN_METHOD(client){
client("tcp://127.0.0.1:5555");
NAN_METHOD(rep_open) {
nng_socket s;
nng_rep0_open(&s); //nng_rep0_open_raw
info.GetReturnValue().Set(WrapPointer(&s, sizeof(nng_socket)));
}

NAN_METHOD(server){
server("tcp://127.0.0.1:5555");
NAN_METHOD(req_open) {
nng_socket s;
nng_req0_open(&s); //nng_req0_open_raw
info.GetReturnValue().Set(WrapPointer(&s, sizeof(nng_socket)));
}

NAN_METHOD(respondent_open) {
nng_socket s;
nng_respondent0_open(&s); //nng_respondent0_open_raw
info.GetReturnValue().Set(WrapPointer(&s, sizeof(nng_socket)));
}

NAN_METHOD(sub_open) {
nng_socket s;
nng_sub0_open(&s); //nng_sub0_open_raw
info.GetReturnValue().Set(WrapPointer(&s, sizeof(nng_socket)));
}

NAN_METHOD(surveyor_open) {
nng_socket s;
nng_surveyor0_open(&s); // nng_surveyor0_open_raw
info.GetReturnValue().Set(WrapPointer(&s, sizeof(nng_socket)));
}

NAN_METHOD(test){
Expand All @@ -159,15 +149,26 @@ NAN_METHOD(test){
return;
}


#define EXPORT_METHOD(C, S) \
Set(C, New(#S).ToLocalChecked(), \
Nan::GetFunction(New<FunctionTemplate>(S)).ToLocalChecked());

NAN_MODULE_INIT(Init) {
HandleScope scope;
EXPORT_METHOD(target, bus_open);
EXPORT_METHOD(target, pair0_open);
EXPORT_METHOD(target, pair1_open);
EXPORT_METHOD(target, pub_open);
EXPORT_METHOD(target, pull_open);
EXPORT_METHOD(target, push_open);
EXPORT_METHOD(target, rep_open);
EXPORT_METHOD(target, req_open);
EXPORT_METHOD(target, respondent_open);
EXPORT_METHOD(target, sub_open);
EXPORT_METHOD(target, surveyor_open);

/* debug */
EXPORT_METHOD(target, test);
EXPORT_METHOD(target, client);
EXPORT_METHOD(target, server);
}
NODE_MODULE(nodenng, Init)
2 changes: 1 addition & 1 deletion compile
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ if [ ! -d nng ]; then
rm -rf deps nng build && mkdir deps
git clone --depth 1 https://github.com/nanomsg/nng && cd nng
mkdir build && cd build
cmake -DCMAKE_INSTALL_MESSAGE=NEVER -DCMAKE_INSTALL_PREFIX=$(pwd)/../../deps .. -DNNG_TESTS=OFF -DNNG_TOOLS=OFF -DNNG_ENABLE_NNGCAT=OFF -DNNG_ENABLE_COVERAGE=OFF
cmake -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_INSTALL_MESSAGE=NEVER -DCMAKE_INSTALL_PREFIX=$(pwd)/../../deps .. -DNNG_TESTS=OFF -DNNG_TOOLS=OFF -DNNG_ENABLE_NNGCAT=OFF -DNNG_ENABLE_COVERAGE=OFF
make MACOSX_DEPLOYMENT_TARGET=10.7 all install
fi
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"test": "node test | tap-spec",
"install": "./compile && node-gyp rebuild"
},
"homepage": "http://github.com/reqhsark/nodenng",
"homepage": "http://github.com/reqshark/nodenng",
"keywords": [
"nng",
"nodenng",
Expand Down
38 changes: 38 additions & 0 deletions readme.markdown
Original file line number Diff line number Diff line change
@@ -1,3 +1,41 @@
# nodenng

bindings to nng (nanomsg next generation)

# install
```bash
npm i nodenng
```

# use
```js
const {
bus_open,
pair0_open,
pair1_open,
pub_open,
pull_open,
push_open,
rep_open,
req_open,
respondent_open,
sub_open,
surveyor_open,
} = require('nodenng')


const pub = pub_open()
const sub = sub_open()

// more nng api will be made available to javascript in the coming days
// please help add stuff or send PRs if you'd like faster access from node.js
```

# test
see [`test` directory](test)

## license

MIT. &copy; 2019 Bent Cardan

<sub>*currently tested on linux and osx but very shortly full windows support*</sub>
Loading

0 comments on commit 787bd7d

Please sign in to comment.