aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/shared/lua_api/load_net.cpp410
1 files changed, 252 insertions, 158 deletions
diff --git a/src/shared/lua_api/load_net.cpp b/src/shared/lua_api/load_net.cpp
index 79e6a80..48bdc84 100644
--- a/src/shared/lua_api/load_net.cpp
+++ b/src/shared/lua_api/load_net.cpp
@@ -1,7 +1,29 @@
/***
The net library
Exposes various structs, constants, and functions for passing messages
+
+A list of protocols that can be used when creating sockets.
+The number values below are only for refrence. You should use net.PAIR, net.BUS,
+ect.
@module net
+@usage
+ local s = net.newsocket()
+ s:bind("tcp://127.0.0.1:8765")
+ s:receive("ping",function(stream)
+ local message = stream:readstring()
+ s:send("pong",function(stream)
+ stream:writestring(message .. " world!")
+ end)
+ end)
+
+@usage
+ local c = net.newsocket()
+ c:receive("pong",function(stream)
+ print(stream:readstring())
+ end)
+ c:send("ping",function(stream)
+ stream:writestring("Hello,")
+ end)
*/
extern "C" {
@@ -14,21 +36,66 @@ extern "C" {
#include <string>
#include <map>
-#include <nn.h>
-#include <tcp.h>
-#include <pair.h>
-#include <ipc.h>
-#include <pipeline.h>
-#include <pubsub.h>
-#include <survey.h>
-#include <bus.h>
+#include <nng.h>
+#include <transport/inproc/inproc.h>
+#include <transport/ipc/ipc.h>
+#include <transport/tcp/tcp.h>
+#include <transport/tls/tls.h>
+#include <transport/zerotier/zerotier.h>
+
+#include <protocol/pair1/pair.h>
+#include <protocol/bus0/bus.h>
+#include <protocol/pubsub0/pub.h>
+#include <protocol/pubsub0/sub.h>
+#include <protocol/pipeline0/pull.h>
+#include <protocol/pipeline0/push.h>
+#include <protocol/reqrep0/req.h>
+#include <protocol/reqrep0/rep.h>
+#include <protocol/survey0/respond.h>
+#include <protocol/survey0/survey.h>
#include "load_net.hpp"
#include <shared/util/hashmap.hpp>
#include "stream.hpp"
-std::map<int,std::map<std::string,int>> netfuncs;
+/***
+1 to 1 protocol.
+@field PAIR 1
+*/
+
+/***
+Many to many protocol.
+When this socket sends messages, it does not receive a copy of the message
+it just sent.
+@field BUS 2
+*/
+
+/***
+@field PUB 3
+@field SUB 4
+@field PULL 5
+@field PUSH 6
+@field REQ 7
+@field REP 8
+@field RESPOND 9
+@field SURVEY 10
+*/
+#define PAIR 1
+#define BUS 2
+#define PUB 3
+#define SUB 4
+#define PULL 5
+#define PUSH 6
+#define REQ 7
+#define REP 8
+#define RESPOND 9
+#define SURVEY 10
+
+std::map<nng_socket*,int> netfuncs;
+
+//Some defines for things that the library dosn't have
+
/***
Read an integer from the stream
@@ -105,11 +172,13 @@ Write an integer to the stream
@function stream:writeint()
@tparam number i The integer to write to the stream
*/
-// stream:writeInt(number)
+// stream:writeint(number)
int lstream_writeint(lua_State* L){//self,number
lua_getfield(L,-2,"data");//self,number,lightuserdata
struct stream* s = (struct stream*)lua_touserdata(L,-1);//self,number,lightuserdata
+ printf("About to print stream...\n");
stream_print(s);
+ printf("Done printing stream\n");
int num = lua_tointeger(L,-2);//self,number,lightuserdata
stream_writeInt(s,num);
lua_pop(L,3);//
@@ -135,19 +204,19 @@ int lstream_writedouble(lua_State* L){
/***
Write some data to the stream
@function stream:writedata()
-@tparam number d The number to write to the stream
+@tparam string data The number to write to the stream
@treturn number The number of bytes written to the stream
*/
// stream:writedata(data)
int lstream_writedata(lua_State* L){
- size_t* datalen = NULL;
- const char* data = lua_tolstring(L,-1,datalen);//{stream},"data"
+ size_t datalen = 0;
+ const char* data = lua_tolstring(L,-1,&datalen);//{stream},"data"
lua_pop(L,1);//{stream}
lua_getfield(L,-1,"data");//{stream},ud_stream
struct stream* s = (struct stream*)lua_touserdata(L,-1);//{stream},ud_stream
- stream_writeData(s,data,*datalen);
+ stream_writeData(s,data,datalen);
lua_pop(L,2);//
- lua_pushinteger(L,*datalen);//size
+ lua_pushinteger(L,datalen);//size
return 1;
}
@@ -161,149 +230,172 @@ Write a string to the stream
int lstream_writestring(lua_State* L){
size_t slen = 0;
const char* str = lua_tolstring(L,-1,&slen);//{stream},"string"
+ slen = strlen(str);
+ char buf[slen];
+ strcpy(buf,str);
lua_pop(L,1);//{stream}
lua_getfield(L,-1,"data");//{stream},ud_stream
struct stream* s = (struct stream*)lua_touserdata(L,-1);//{stream},ud_stream
- stream_writeString(s,str,slen);
+ stream_writeString(s,buf,slen);
lua_pop(L,2);
return 0;
}
void gameloop_net(lua_State* L){
//printf("Doing net of gameloop\n");
- for(std::map<int,std::map<std::string,int>>::iterator it = netfuncs.begin(); it != netfuncs.end(); ++it){
+ for(std::map<nng_socket*,int>::iterator it = netfuncs.begin(); it != netfuncs.end(); ++it){
+ //printf("In for socket %d\n");
char* buf = NULL;
- int bytes = nn_recv(it->first, &buf, NN_MSG,NN_DONTWAIT);
- if(bytes < 0 && nn_errno() != EAGAIN){
- lua_pushstring(L,"Failed to receive");
- lua_error(L);
- }else if( bytes < 0 && nn_errno() == EAGAIN){
+ size_t size;
+ int err = nng_recv(*(it->first), &buf, &size, NNG_FLAG_NONBLOCK | NNG_FLAG_ALLOC);
+ //printf("Got bytes: %d EAGAIN:%d\n",bytes,EAGAIN);
+ if(err != 0 && err != NNG_EAGAIN){
+ printf("Net error: %s\n\t err: %d\n\teagain:%d\n",nng_strerror(err),err,NNG_EAGAIN);
+ //lua_pushstring(L,"Failed to receive");
+ //lua_error(L);
+ }else if(err == NNG_EAGAIN){
//do nothing
}else{
//find how long until the first null character
struct stream* stream = stream_create();
- stream->length = bytes;
+ stream->length = size;
stream->data = buf;
stream_print(stream);
- char* msg = stream_readString(stream);
- std::map<std::string,int> themap = it->second;
- std::string s = std::string(msg);
- std::map<std::string,int>::iterator in = themap.find(s);
- if(in != themap.end()){
- lua_rawgeti(L,LUA_REGISTRYINDEX,(*in).second);//function(stream)
- lua_newtable(L);//function(stream),{}
- lua_pushlightuserdata(L,stream);//function(stream),{},ud_stream
- lua_setfield(L,-2,"data");//function(stream),{data=ud_stream}
- luaL_getmetatable(L,"net.stream");//function(stream),{data=ud_stream},{m_net.stream}
- lua_setmetatable(L,-2);//function(stream),{stream}
- lua_call(L,1,0);//
+ int f = it->second;
+ if(f == -1){//not set yet
+ lua_pushstring(L,"Got message for a socket without a receiving function");
+ lua_error(L);
}
- nn_freemsg(buf);
+ lua_rawgeti(L,LUA_REGISTRYINDEX,f);//function(stream)
+ lua_newtable(L);//function(stream),{}
+ lua_pushlightuserdata(L,stream);//func,{},ud_stream
+ lua_setfield(L,-2,"data");//func,{data=stream}
+ luaL_getmetatable(L,"net.stream");//func,{data=stream}
+ lua_setmetatable(L,-2);//func,{stream}
+ lua_call(L,1,0);//
+ printf("Finished calling gameloop\n");
+ nng_free(buf,size);
+ printf("called nn_freemsg\n");
free(stream);//We manually set stream->data so free_stream would crash here
+ printf("Called free on stream\n");
}
}
}
/***
+Bind a socket to a network interface
@function socket:bind
@tparam string where Where to connect this socket to
-@usage
-local s = net.newsocket()
-s:bind("tcp://127.0.0.1:8765")
-s:receive("ping",function(stream)
- print(instream:readstring())
-end)
-local c = net.newsocket()
-c:connect("127.0.0.1")
*/
-//bind({self},"where")
+//bind("where")
int bindsocket(lua_State*L){
const char* s = lua_tostring(L,-1);//{self},"where"
lua_pop(L,1);//{self}
lua_getfield(L,-1,"fd");//{self},num_socket
- int fd = (int)lua_tonumber(L,-1);
+ nng_socket *fd = (nng_socket*)lua_touserdata(L,-1);
lua_pop(L,1);//{self}
- int id = nn_bind(fd,s);
- if(id < 0){
- printf("Socket error\n");
- const char* errstr = nn_strerror(nn_errno());
+ printf("Binding socket %p to %s\n",fd,s);
+ int err = nng_listen(*fd,s,NULL,0);
+ if(err != 0){
+ const char* errstr = nng_strerror(err);
char* failmsg = (char*)"Failed to bind socket: ";
int faillen = strlen(failmsg + 2);
char buf[faillen + strlen(errstr)];
sprintf(buf,"%s%s\n",failmsg,errstr);
+ printf("Socket error:%s\n",buf);
lua_pushstring(L,buf);
lua_error(L);
}
- lua_pushinteger(L,id);//{self},endpoint
+ lua_pushlightuserdata(L,fd);//{self},endpoint
lua_setfield(L,-2,"endpoint");//{self}
- netfuncs[fd] = std::map<std::string,int>();
return 0;
}
+/***
+Connects a socket to another
+@function socket:connect()
+@tparam string endpoint The endpoint to connect this socket to
+*/
+//socket:connect("endpoint")
int connectsocket(lua_State* L){
- const char* s = lua_tostring(L,-1);
- lua_pushstring(L,"fd");
- lua_gettable(L,-2);
- int fd = lua_tonumber(L,-1);
+ printf("Connect called\n");
+ const char* s = lua_tostring(L,-1);//{self},"endpoint"
+ lua_pop(L,1);//{self}
+ lua_getfield(L,-1,"fd");//{self},ud_nng_socket
+ nng_socket *fd = (nng_socket*)lua_touserdata(L,-1);//{self},ud_nng_socket
+ printf("Got socket: %p\n",fd);
lua_pop(L,2);
- int id = nn_connect(fd,s);
-
- lua_pushstring(L,"endpoint");
- lua_pushinteger(L,id);
- lua_settable(L,-3);
-
- netfuncs[fd] = std::map<std::string,int>();
-
+ int err = nng_dial(*fd,s,NULL,0);
+ if(err != 0){
+ printf("Connect error: %s\n",nng_strerror(err));
+ }
return 0;
}
-//socket:send("name",function(stream))
+/***
+Sends some message to the other side of a connected or bound socket
+@function socket:send
+@tparam function callback The function to call to send the data
+*/
+//socket:send(function(stream))
int send(lua_State* L){
- const char* data = lua_tostring(L,-2);//{socket},"name",function(stream)
- lua_getfield(L,-3,"fd");//{socket},"name",function(stream),int_socketdescriptor
- int fd = lua_tonumber(L,-1);//socket,"name",function(stream),int_socketdescriptor
- lua_pop(L,1);//socket,"name",function(stream)
- int dlen = strlen(data);
+ lua_getfield(L,-2,"fd");//{socket},function(stream),int_socketdescriptor
+ nng_socket *fd = (nng_socket*)lua_touserdata(L,-1);//socket,function(stream),int_socketdescriptor
+ lua_pop(L,1);//socket,function(stream)
struct stream* s = stream_create();
- stream_writeString(s,data,dlen);
- lua_newtable(L);//socket,"name",function(stream),streamtable
- luaL_getmetatable(L,"net.stream");//socket,"name",function(stream),streamtable,net.stream
- lua_setmetatable(L,-2);//socket,"name",function(stream),streamtable
- lua_pushlightuserdata(L,s);//socket,"name",function(stream),streamtable,lightudata
- lua_setfield(L,-2,"data");//socket,"name",function(stream),streamtable
- lua_call(L,1,0);//socket,"name"
- lua_pop(L,2);//
- int err = nn_send(fd,s->data,s->length,0);
+ lua_newtable(L);//socket,function(stream),streamtable
+ luaL_getmetatable(L,"net.stream");//socket,function(stream),streamtable,net.stream
+ lua_setmetatable(L,-2);//socket,function(stream),streamtable
+ lua_pushlightuserdata(L,s);//socket,function(stream),streamtable,lightudata
+ lua_setfield(L,-2,"data");//socket,function(stream),streamtable
+ lua_call(L,1,0);//socket,
+ printf("Finished the stream call\n");
+ lua_pop(L,1);//
+ printf("About to nn_send\n\tfd:%p\n\t%s\n\t%ld\n",fd,s->data,s->length);
+ int err = nng_send(*fd, s->data, s->length,0);
+ printf("Finished nn_send\n");
stream_free(s);
- if(err < 0){
- const char* errstr = nn_strerror(nn_errno());
- char* failmsg = (char*)"Failed to bind socket: ";
+ if(err != 0){
+ printf("Errored somewhere\n");
+ const char* errstr = nng_strerror(err);
+ char* failmsg = (char*)"Failed to send socket: ";
int faillen = strlen(failmsg + 2);
char buf[faillen + strlen(errstr)];
lua_pushstring(L,buf);
lua_error(L);
}
+ printf("No error in nn_send\n");
return 0;
}
/***
-@function net.receive
-@tparam string message The message to bind this function to
+@function socket:receive()
@tparam function callback The function to call when this message is received
*/
//LUA:
-//socket:receive(s_name,function(stream))
+//socket:receive(function(stream))
int netreceive(lua_State* L){
- const char* name = lua_tostring(L,-2);
- //int slen = strlen(name);
- std::string s = std::string(name);
- int func = luaL_ref(L,LUA_REGISTRYINDEX);
- lua_pushstring(L,"fd");
- lua_gettable(L,-2);
- int fd = lua_tonumber(L,-1);
- lua_pop(L,1);
- netfuncs[fd].insert(std::pair<std::string, int>(s,func));
+ int func = luaL_ref(L,LUA_REGISTRYINDEX);//{socket}
+ lua_getfield(L,-1,"fd");//{socket},fd
+ nng_socket *fd = (nng_socket*)lua_touserdata(L,-1);//{socket},fd
+ lua_pop(L,2);//
+ netfuncs[fd] = func;//
+ return 0;
+}
+
+/***
+@function socket:close()
+Closes the socket
+*/
+//socket:close()
+int netclose(lua_State* L){
+ lua_getfield(L,-1,"fd");
+ nng_socket *fd = (nng_socket*)lua_touserdata(L,-1);
+ lua_pop(L,2);
+ nng_close(*fd);
+ netfuncs.erase(fd);
+ free(fd);
return 0;
}
@@ -318,45 +410,49 @@ int netreceive(lua_State* L){
@return net.socket
@domain shared
*/
-//net.newsocket(domain, type)
+//net.newsocket(type)
int socketFactory(lua_State*L){
- //int domain = luaL_optint(L,-1,0);
- //int type = luaL_optint(L,-2,0);
-
- int c = nn_socket(AF_SP,NN_PAIR);
- if(c < 0){
- lua_pushstring(L,"Failed to create socket");
+ int nargs = lua_gettop(L);
+ if(nargs != 1){
+ printf("net.newsocket() expected 1 argument, got %d\n",nargs);
+ return 0;
+ }
+
+ int type = lua_tonumber(L,-1);
+ lua_pop(L,1);
+ printf("Creating a socket with type: %d, NNG_PAIR:%d\n",type,PAIR);
+ nng_socket *socket = (nng_socket*) malloc(sizeof(nng_socket));
+ int err;
+ switch(type){
+ case PAIR: err = nng_pair1_open(socket); break;
+ case BUS : err = nng_bus0_open(socket); break;
+ case PUB : err = nng_pub0_open(socket); break;
+ case SUB : err = nng_sub0_open(socket); break;
+ case PULL: err = nng_pull0_open(socket); break;
+ case PUSH: err = nng_push0_open(socket); break;
+ case REQ : err = nng_req0_open(socket); break;
+ case REP : err = nng_rep0_open(socket); break;
+ case SURVEY : err = nng_surveyor0_open(socket); break;
+ case RESPOND : err = nng_respondent0_open(socket); break;
+ default:
+ printf("Unknown socket type: %d",type);
+ break;
+ }
+ if(err != 0){
+ printf("Failed to create socket: %s\n",nng_strerror(err));
+ lua_pushstring(L,"Failed to create socket:");
+ lua_pushstring(L,nng_strerror(err));
+ lua_concat(L,2);
lua_error(L);
}
+ printf("Socket created: %p\n",socket);
lua_newtable(L);//{}
- lua_pushinteger(L,c);//{},c
+ lua_pushlightuserdata(L,socket);//{},c
lua_setfield(L,-2,"fd");//{fd=c}
- luaL_getmetatable(L,"net.socket");//{},{m_net.socket}
+ luaL_getmetatable(L,"net.pair_socket");//{},{m_net.pair_socket}
lua_setmetatable(L,-2);//{socket}
-
- //lua_newtable(L);
-
- //lua_pushstring(L,"fd");
- //lua_pushinteger(L,c);
- //lua_settable(L,-3);
-
- //lua_pushstring(L,"bind");
- //lua_pushcfunction(L,bindsocket);
- //lua_settable(L,-3);
-
- //lua_pushstring(L,"connect");
- //lua_pushcfunction(L,connectsocket);
- //lua_settable(L,-3);
-
- //lua_pushstring(L,"send");
- //lua_pushcfunction(L,send);
- //lua_settable(L,-3);
-
- //lua_pushstring(L,"receive");
- //lua_pushcfunction(L,netreceive);
- //lua_settable(L,-3);
-
+ printf("Finished making the socket, returning\n");
return 1;
}
@@ -365,7 +461,7 @@ static const struct luaL_Reg stream_m[] = {
{"writedouble",lstream_writedouble},
{"writedata",lstream_writedata},
{"writestring",lstream_writestring},
-
+
{"readint",lstream_readint},
{"readdouble",lstream_readdouble},
{"readdata",lstream_readdata},
@@ -374,52 +470,48 @@ static const struct luaL_Reg stream_m[] = {
{NULL,NULL}
};
-static const struct luaL_Reg socket_m[] = {
+static const struct luaL_Reg pair_socket_m[] = {
{"bind", bindsocket},
{"connect", connectsocket},
{"send",send},
{"receive", netreceive},
+ {"close",netclose},
{NULL,NULL}
};
+
static const struct luaL_Reg net_f[] = {
{"newsocket", socketFactory},
{NULL,NULL}
};
+int notify_gc(lua_State* L){
+ printf("Garbage collector called!");
+ return 0;
+}
+
#define set_const(l,x) lua_pushstring(l,#x);lua_pushinteger(l,x);lua_settable(l,-3);
void loadNetLibs(lua_State* L){
+ //Initalize the socket->function map
+
//A table to hold all our net funcs
lua_newtable(L);//{}
-
+
//Push some enums
- set_const(L,AF_SP);
- set_const(L,AF_SP_RAW);
-
- set_const(L,NN_PROTO_PAIR);
- set_const(L,NN_PAIR);
- set_const(L,NN_SUB);
- set_const(L,NN_SUB_SUBSCRIBE);
- set_const(L,NN_PUB);
- set_const(L,NN_SUB_UNSUBSCRIBE);
-
- set_const(L,NN_PUSH);
- set_const(L,NN_PULL);
- set_const(L,NN_PROTO_PIPELINE);
- set_const(L,NN_PROTO_SURVEY);
- set_const(L,NN_SURVEYOR);
- set_const(L,NN_RESPONDENT);
- set_const(L,NN_SURVEYOR_DEADLINE);
- set_const(L,NN_TCP_NODELAY);
- set_const(L,NN_TCP);
- set_const(L,NN_PROTO_BUS);
- set_const(L,NN_BUS);
-
- set_const(L,NN_DONTWAIT);
- set_const(L,PROTO_SP);
- set_const(L,SP_HDR);
-
- luaL_register(L,NULL,net_f);
+ //Protocols
+
+ set_const(L,PAIR);
+ set_const(L,BUS);
+ set_const(L,PUB);
+ set_const(L,SUB);
+ set_const(L,PULL);
+ set_const(L,PUSH);
+ set_const(L,REQ);
+ set_const(L,REP);
+ set_const(L,RESPOND);
+ set_const(L,SURVEY);
+
+ luaL_register(L,NULL,net_f);
//Set the table to gobal "net"
lua_setglobal(L,"net");
@@ -429,12 +521,14 @@ void loadNetLibs(lua_State* L){
lua_newtable(L);//net.stream,{}
luaL_register(L,NULL,stream_m);//net.stream,{net.stream}
lua_setfield(L,-2,"__index");//{m_net.stream}
+ //lua_pushcfunction(L,notify_gc);//{m_net.stream},notify_gc
+ //lua_setfield(L,-2,"__gc");//{m_net.stream}
lua_pop(L,1);//
//Create the metatable for sockets
- luaL_newmetatable(L,"net.socket");//net.socket
+ luaL_newmetatable(L,"net.pair_socket");//net.socket
lua_newtable(L);//net.socket,{}
- luaL_register(L,NULL,socket_m);//net.socket,{net.socket}
+ luaL_register(L,NULL,pair_socket_m);//net.socket,{net.socket}
lua_setfield(L,-2,"__index");//{m_net.socket}
lua_pop(L,1);//
}