diff options
| author | Alexander Pickering <alex@cogarr.net> | 2018-07-31 16:40:58 -0400 |
|---|---|---|
| committer | Alexander Pickering <alex@cogarr.net> | 2018-07-31 16:40:58 -0400 |
| commit | 11857adbdce423ca93980c884d3dc94a974f735f (patch) | |
| tree | cececf1fa46d77de1225265ad84a0961391870d4 /src | |
| parent | 09465197e0e7634e1bc5d992e8f2898ad73c83b9 (diff) | |
| download | brokengine-11857adbdce423ca93980c884d3dc94a974f735f.tar.gz brokengine-11857adbdce423ca93980c884d3dc94a974f735f.tar.bz2 brokengine-11857adbdce423ca93980c884d3dc94a974f735f.zip | |
Moved from nanomsg to nng
Moved the networking code from nanomsg to nanomsg-next-gen.
Created/Renamed/Documented some constants related to networking.
Diffstat (limited to 'src')
| -rw-r--r-- | src/shared/lua_api/load_net.cpp | 410 |
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);// } |
