int syslog_init (void *inst, struct skynet_context *ctx, const char *ident) { openlog (ident, LOG_PID, LOG_LOCAL3); skynet_callback (ctx, NULL, cb); skynet_command (ctx, "REG", ".logger"); return 0; }
int broker_init(struct broker *b, struct skynet_context *ctx, const char * args) { b->launcher = skynet_queryname(ctx, LAUNCHER); if (b->launcher == 0) { skynet_error(ctx, "Can't query %s", LAUNCHER); return 1; } char * service = strchr(args,' '); if (service == NULL) { return 1; } int len = service - args; if (len>0) { b->name = malloc(len +1); memcpy(b->name, args, len); b->name[len] = '\0'; } service++; int i; len = strlen(service); if (len == 0) return 1; for (i=0;i<DEFAULT_NUMBER;i++) { int id = skynet_send(ctx, 0, b->launcher , -1, service , len, 0); assert(id > 0 && id <= DEFAULT_NUMBER); } skynet_callback(ctx, b, _cb); return 0; }
int localcast_init(void * ud, struct skynet_context *ctx, const char * args) { skynet_callback(ctx, ud, _maincb); skynet_command(ctx, "REG", ".cast"); return 0; }
MASTER_API int master_init(struct master *m, struct skynet_context *ctx, const char * args) { //char tmp[strlen(args) + 32]; char tmp[256]; sprintf(tmp,"gate L ! %s %d %d 0",args,PTYPE_HARBOR,REMOTE_MAX); const char * gate_addr = skynet_command(ctx, "LAUNCH", tmp); if (gate_addr == NULL) { skynet_error(ctx, "Master : launch gate failed"); return 1; } uint32_t gate = strtoul(gate_addr+1, NULL, 16); if (gate == 0) { skynet_error(ctx, "Master : launch gate invalid %s", gate_addr); return 1; } const char * self_addr = skynet_command(ctx, "REG", NULL); int n = sprintf(tmp,"broker %s",self_addr); skynet_send(ctx, 0, gate, PTYPE_TEXT, 0, tmp, n); skynet_send(ctx, 0, gate, PTYPE_TEXT, 0, "start", 5); skynet_callback(ctx, m, _mainloop); m->ctx = ctx; return 0; }
int gate_init(struct gate *g , struct skynet_context * ctx, char * parm) { if (parm == NULL) return 1; int max = 0; int buffer = 0; int sz = strlen(parm)+1; char watchdog[sz]; char binding[sz]; int client_tag = 0; char header; int n = sscanf(parm, "%c %s %s %d %d %d",&header,watchdog, binding,&client_tag , &max,&buffer); if (n<4) { skynet_error(ctx, "Invalid gate parm %s",parm); return 1; } if (max <=0 ) { skynet_error(ctx, "Need max connection"); return 1; } if (header != 'S' && header !='L') { skynet_error(ctx, "Invalid data header style"); return 1; } if (client_tag == 0) { client_tag = PTYPE_CLIENT; } if (watchdog[0] == '!') { g->watchdog = 0; } else { g->watchdog = skynet_queryname(ctx, watchdog); if (g->watchdog == 0) { skynet_error(ctx, "Invalid watchdog %s",watchdog); return 1; } } g->ctx = ctx; int cap = 16; while (cap < max) { cap *= 2; } hashid_init(&g->hash, max, cap); g->conn = malloc(max * sizeof(struct connection)); memset(g->conn, 0, max *sizeof(struct connection)); g->max_connection = max; int i; for (i=0;i<max;i++) { g->conn[i].id = -1; } g->client_tag = client_tag; g->header_size = header=='S' ? 2 : 4; skynet_callback(ctx,g,_cb); return start_listen(g,binding); }
static int _callback(lua_State *L) { struct snlua *lua = lua_touserdata(L, lua_upvalueindex(1)); if (lua == NULL || lua->ctx == NULL) { return luaL_error(L, "Init skynet context first"); } struct skynet_context * context = lua->ctx; luaL_checktype(L,1,LUA_TFUNCTION); lua_settop(L,1); lua_rawsetp(L, LUA_REGISTRYINDEX, _cb); lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_MAINTHREAD); lua_State *gL = lua_tothread(L,-1); struct stat * S = lua_newuserdata(L, sizeof(*S)); memset(S, 0, sizeof(*S)); S->L = gL; S->trace = trace_create(); S->lua = lua; lua_createtable(L,0,1); lua_pushcfunction(L, _delete_stat); lua_setfield(L,-2,"__gc"); lua_setmetatable(L, -2); lua_rawsetp(L, LUA_REGISTRYINDEX, _stat); skynet_callback(context, S, _cb); return 0; }
HARBOR_API int harbor_init(struct harbor *h, struct skynet_context *ctx, const char * args) { h->ctx = ctx; int sz = strlen(args)+1; //char master_addr[sz]; //char local_addr[sz]; char master_addr[100]; char local_addr[100]; int harbor_id = 0; sscanf(args,"%s %s %d",master_addr, local_addr, &harbor_id); h->master_addr = skynet_strdup(master_addr); h->id = harbor_id; h->master_fd = _connect_to(h, master_addr, true); if (h->master_fd == -1) { fprintf(stderr, "Harbor: Connect to master failed\n"); exit(1); } h->local_addr = skynet_strdup(local_addr); _launch_gate(ctx, local_addr); skynet_callback(ctx, h, _mainloop); _request_master(h, local_addr, strlen(local_addr), harbor_id); return 0; }
static int _callback(lua_State *L) { struct skynet_context * context = lua_touserdata(L, lua_upvalueindex(1)); int forward = lua_toboolean(L, 2); luaL_checktype(L,1,LUA_TFUNCTION); lua_settop(L,1); lua_rawsetp(L, LUA_REGISTRYINDEX, _cb); lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_MAINTHREAD); lua_State *gL = lua_tothread(L,-1); if (forward) { skynet_callback(context, gL, forward_cb); } else { skynet_callback(context, gL, _cb); } return 0; }
int otu_init(struct otu *u , struct skynet_context * ctx, char * parm) { if (parm == NULL) return 1; int max = 0; int sz = strlen(parm)+1; char watchdog[sz]; char binding[sz]; int client_tag = 0; int n = sscanf(parm, "%s %s %d %d", watchdog, binding, &client_tag, &max); if (n<4) { skynet_error(ctx, "Invalid otu parm %s", parm); return 1; } skynet_error(ctx, "Watchdog:%s, Binding:%s, Protocol:%d, MaxPeer:%d", watchdog, binding, client_tag, max); if (max <=0 ) { skynet_error(ctx, "Need max connection"); return 1; } if (client_tag == 0) { client_tag = PTYPE_CLIENT; } if (watchdog[0] == '!') { u->watchdog = 0; } else { u->watchdog = skynet_queryname(ctx, watchdog); if (u->watchdog == 0) { skynet_error(ctx, "Invalid watchdog %s",watchdog); return 1; } } u->ctx = ctx; hashid64_init(&u->hash, max); u->peer = skynet_malloc(max * sizeof(struct udp_peer)); memset(u->peer, 0, max *sizeof(struct udp_peer)); u->max_peer = max; int i; for (i=0;i<max;i++) { // u->peer[i].id = -1; } u->client_tag = client_tag; skynet_callback(ctx,u,_cb_otu); return start_service(u,binding); }
static int _launch(struct skynet_context * context, void *ud, int type, int session, uint32_t source , const void * msg, size_t sz) { assert(type == 0 && session == 0); struct snlua *l = ud; skynet_callback(context, NULL, NULL); int err = _init(l, context, msg, sz); if (err) { skynet_command(context, "EXIT", NULL); } return 0; }
int snlua_init(struct snlua *l, struct skynet_context *ctx, const char * args) { int sz = strlen(args); char * tmp = skynet_malloc(sz); memcpy(tmp, args, sz); skynet_callback(ctx, l , _launch); const char * self = skynet_command(ctx, "REG", NULL); uint32_t handle_id = strtoul(self+1, NULL, 16); // it must be first message skynet_send(ctx, 0, handle_id, PTYPE_TAG_DONTCOPY,0, tmp, sz); return 0; }
static int launch_cb(struct skynet_context * context, void *ud, int type, int session, uint32_t source , const void * msg, size_t sz) { assert(type == 0 && session == 0); struct snlua *l = ud; skynet_callback(context, NULL, NULL); // 将消息处理函数置空,以免别的消息发过来 int err = init_cb(l, context, msg, sz); // 消息处理:通过 loader.lua 加载 lua 代码块 if (err) { skynet_command(context, "EXIT", NULL); } return 0; }
int tunnel_init(void * dummy, struct skynet_context *ctx, const char * args) { uint32_t dest = skynet_queryname(ctx, args); if (dest == 0) { skynet_error(ctx, "Can't create tunnel to %s",args); return 1; } skynet_callback(ctx, (void*)(intptr_t)dest, _cb); return 0; }
int snlua_init(struct snlua *l, struct skynet_context *ctx, const char * args) { int sz = strlen(args); char * tmp = skynet_malloc(sz); memcpy(tmp, args, sz); skynet_callback(ctx, l , launch_cb); // 注册消息处理函数 const char * self = skynet_command(ctx, "REG", NULL); // 得到自身的服务的地址,是一个带冒号的字符串 uint32_t handle_id = strtoul(self+1, NULL, 16); // 得到数字地址 // it must be first message //直接发送消息,以便snlua能第一个加载 相应的服务 skynet_send(ctx, 0, handle_id, PTYPE_TAG_DONTCOPY,0, tmp, sz); // 发消息给自己以便加载相应的服务模块 return 0; }
int package_init(struct package * P, struct skynet_context *ctx, const char * param) { int n = sscanf(param ? param : "", "%u %d", &P->manager, &P->fd); if (n != 2 || P->manager == 0 || P->fd == 0) { skynet_error(ctx, "Invalid param [%s]", param); return 1; } skynet_socket_start(ctx, P->fd); skynet_socket_nodelay(ctx, P->fd); heartbeat(ctx, P); skynet_callback(ctx, P, message_handler); return 0; }
static int _callback(lua_State *L) { struct skynet_context * context = (struct skynet_context *)lua_touserdata(L, lua_upvalueindex(1)); luaL_checktype(L,1,LUA_TFUNCTION); lua_settop(L,1); lua_rawsetp(L, LUA_REGISTRYINDEX, _cb); lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_MAINTHREAD); lua_State *gL = lua_tothread(L,-1); skynet_callback(context, gL, _cb); return 0; }
static int _launch(struct skynet_context * context, void *ud, int type, int session, uint32_t source , const void * msg, size_t sz) { assert(type == 0 && session == 0); struct snlua *l = ud; skynet_callback(context, NULL, NULL); struct timespec ti; current_time(&ti); int err = _init(l, context, msg); double t = diff_time(&ti); lua_pushnumber(l->L, t); lua_setfield(l->L, LUA_REGISTRYINDEX, "skynet_boottime"); if (err) { skynet_command(context, "EXIT", NULL); } return 0; }
//初始化某个snlua服务,snlua在create时创建了一个lua虚拟机 //l, 服务实例 //ctx,与服务实例关联的一些上下文配置资源 //args,参数{通常为脚本名} int snlua_init(struct snlua *l, struct skynet_context *ctx, const char * args) { //复制参数 int sz = strlen(args); char * tmp = skynet_malloc(sz); memcpy(tmp, args, sz); //设置启动回调 skynet_callback(ctx, l , launch_cb); //注册一个服务名称,如果没用字符串,直接返回16进制格式返回服务":唯一ID" //否则注册一个字符串格式的名字 const char * self = skynet_command(ctx, "REG", NULL); uint32_t handle_id = strtoul(self+1, NULL, 16); // it must be first message //由框架向目标服务handle_id投递一个消息,必须保证这是服务的接收的第一条消息, 消息的内容是调用参数{脚本名,session设置为0表示不需要回应} skynet_send(ctx, 0, handle_id, PTYPE_TAG_DONTCOPY,0, tmp, sz); return 0; }
LOGGER_API int logger_init(struct logger * inst, struct skynet_context *ctx, const char * parm) { if (parm) { inst->handle = fopen(parm,"w"); if (inst->handle == NULL) { return 1; } inst->close = 1; } else { inst->handle = stdout; } if (inst->handle) { skynet_callback(ctx, inst, _logger); skynet_command(ctx, "REG", ".logger"); return 0; } return 1; }
int connection_init(struct connection_server * server, struct skynet_context * ctx, char * param) { server->pool = connection_newpool(DEFAULT_CONNECTION); if (server->pool == NULL) return 1; server->max_connection = strtol(param, NULL, 10); if (server->max_connection == 0) { server->max_connection = DEFAULT_CONNECTION; } server->current_connection = 0; server->ctx = ctx; server->conn = malloc(server->max_connection * sizeof(struct connection)); memset(server->conn, 0, server->max_connection * sizeof(struct connection)); skynet_callback(ctx, server, _connection_main); skynet_command(ctx,"REG",".connection"); skynet_command(ctx,"TIMEOUT","0"); return 0; }
int logger_init(struct logger * inst, struct skynet_context *ctx, const char * parm) { if (parm) { inst->handle = fopen(parm,"w"); if (inst->handle == NULL) { return 1; } inst->filename = skynet_malloc(strlen(parm)+1); strcpy(inst->filename, parm); inst->close = 1; } else { inst->handle = stdout; } if (inst->handle) { skynet_callback(ctx, inst, logger_cb); skynet_command(ctx, "REG", ".logger"); return 0; } return 1; }
int harbor_init(struct harbor *h, struct skynet_context *ctx, const char * args) { int sz = strlen(args)+1; char master_addr[sz]; char local_addr[sz]; int harbor_id = 0; sscanf(args,"%s %s %d",master_addr, local_addr, &harbor_id); int master_fd = _connect_to(ctx, master_addr); if (master_fd < 0) { skynet_error(ctx, "Harbor : Connect to master %s faild",master_addr); return 1; } printf("Connect to master %s\n",master_addr); h->master_addr = strdup(master_addr); h->master_fd = master_fd; char tmp[128]; sprintf(tmp,"gate L ! %s %d %d 0",local_addr, PTYPE_HARBOR, REMOTE_MAX); const char * gate_addr = skynet_command(ctx, "LAUNCH", tmp); if (gate_addr == NULL) { skynet_error(ctx, "Harbor : launch gate failed"); return 1; } uint32_t gate = strtoul(gate_addr+1 , NULL, 16); if (gate == 0) { skynet_error(ctx, "Harbor : launch gate invalid %s", gate_addr); return 1; } const char * self_addr = skynet_command(ctx, "REG", NULL); int n = sprintf(tmp,"broker %s",self_addr); skynet_send(ctx, 0, gate, PTYPE_TEXT, 0, tmp, n); skynet_send(ctx, 0, gate, PTYPE_TEXT, 0, "start", 5); h->id = harbor_id; skynet_callback(ctx, h, _mainloop); _report_local_address(h, ctx, local_addr, harbor_id); return 0; }
int logger_init(struct logger * inst, struct skynet_context *ctx, const char * parm) { if (parm) { inst->handle = fopen(parm,"w"); if (inst->handle == NULL) { return 1; } inst->close = 1; } else { inst->handle = stdout; } #ifdef _MSC_VER _wsetlocale(0, L"chs"); #endif if (inst->handle) { skynet_callback(ctx, inst, _logger); skynet_command(ctx, "REG", ".logger"); return 0; } return 1; }
static int _cb(struct skynet_context * context, void * ud, int session, uint32_t source, const void * msg, size_t sz) { assert(sz <= 65535); int fd = (int)(intptr_t)ud; struct iovec buffer[2]; // send big-endian header uint8_t head[2] = { sz >> 8 & 0xff , sz & 0xff }; buffer[0].iov_base = head; buffer[0].iov_len = 2; buffer[1].iov_base = (void *)msg; buffer[1].iov_len = sz; for (;;) { int err = writev(fd, buffer, 2); if (err < 0) { switch (errno) { case EAGAIN: case EINTR: continue; } } if (err < 0) { skynet_error(context, "Client socket error : Drop message from %x session = %d", source, session); return 0; } assert(err == sz +2); return 0; } } int client_init(void * dummy, struct skynet_context *ctx, const char * args) { int fd = strtol(args, NULL, 10); skynet_callback(ctx, (void*)(intptr_t)fd, _cb); return 0; }
static int _cb(struct skynet_context * context, void * ud, int type, int session, uint32_t source, const void * msg, size_t sz) { struct stat *S = ud; lua_State *L = S->L; struct timespec ti; _stat_begin(S, &ti); int trace = 1; int top = lua_gettop(L); if (top == 1) { lua_rawgetp(L, LUA_REGISTRYINDEX, _cb); } else { assert(top == 2); lua_pushvalue(L,2); } lua_pushinteger(L, type); lua_pushlightuserdata(L, (void *)msg); lua_pushinteger(L,sz); lua_pushinteger(L, session); lua_pushnumber(L, source); int r = lua_pcall(L, 5, 0 , trace); _stat_end(S, &ti); if (r == LUA_OK) { if (S->lua->reload) { skynet_callback(context, NULL, 0); struct snlua * lua = S->lua; assert(lua->L == L); const char * cmd = lua->reload; lua->reload = NULL; lua->L = luaL_newstate(); int err = lua->init(lua, context, cmd); if (err) { skynet_callback(context, S, _cb); skynet_error(context, "lua reload failed : %s", cmd); lua_close(lua->L); lua->L = L; } else { skynet_error(context, "lua reload %s", cmd); lua_close(L); } } return 0; } const char * self = skynet_command(context, "REG", NULL); switch (r) { case LUA_ERRRUN: skynet_error(context, "lua call [%x to %s : %d msgsz = %d] error : " KRED "%s" KNRM, source , self, session, sz, lua_tostring(L,-1)); break; case LUA_ERRMEM: skynet_error(context, "lua memory error : [%x to %s : %d]", source , self, session); break; case LUA_ERRERR: skynet_error(context, "lua error in error : [%x to %s : %d]", source , self, session); break; case LUA_ERRGCMM: skynet_error(context, "lua gc error : [%x to %s : %d]", source , self, session); break; }; lua_pop(L,1); return 0; }
int gate_init(struct gate *g , struct skynet_context * ctx, char * parm) { int port = 0; int max = 0; int buffer = 0; int sz = strlen(parm)+1; char watchdog[sz]; char binding[sz]; int client_tag = 0; char header; int n = sscanf(parm, "%c %s %s %d %d %d",&header,watchdog, binding,&client_tag , &max,&buffer); if (n<4) { skynet_error(ctx, "Invalid gate parm %s",parm); return 1; } if (max <=0 ) { skynet_error(ctx, "Need max conntection"); return 1; } if (header != 'S' && header !='L') { skynet_error(ctx, "Invalid data header style"); return 1; } if (client_tag == 0) { client_tag = PTYPE_CLIENT; } char * portstr = strchr(binding,':'); uint32_t addr = INADDR_ANY; if (portstr == NULL) { port = strtol(binding, NULL, 10); if (port <= 0) { skynet_error(ctx, "Invalid gate address %s",parm); return 1; } } else { port = strtol(portstr + 1, NULL, 10); if (port <= 0) { skynet_error(ctx, "Invalid gate address %s",parm); return 1; } portstr[0] = '\0'; addr=inet_addr(binding); } struct mread_pool * pool = mread_create(addr, port, max, buffer); if (pool == NULL) { skynet_error(ctx, "Create gate %s failed",parm); return 1; } if (watchdog[0] == '!') { g->watchdog = 0; } else { g->watchdog = skynet_queryname(ctx, watchdog); if (g->watchdog == 0) { skynet_error(ctx, "Invalid watchdog %s",watchdog); return 1; } } g->pool = pool; int cap = 1; while (cap < max) { cap *= 2; } g->cap = cap; g->max_connection = max; g->id_index = 0; g->client_tag = client_tag; g->header_size = header=='S' ? 2 : 4; g->agent = malloc(cap * sizeof(struct connection *)); memset(g->agent, 0, cap * sizeof(struct connection *)); g->map = malloc(max * sizeof(struct connection)); memset(g->map, 0, max * sizeof(struct connection)); int i; for (i=0;i<max;i++) { g->map[i].connection_id = i; } skynet_callback(ctx,g,_cb); return 0; }
int gate_init(struct gate *g , struct skynet_context * ctx, char * parm) { int port = 0; int max = 0; int buffer = 0; int sz = strlen(parm)+1; char watchdog[sz]; char binding[sz]; int n = sscanf(parm, "%s %s %d %d",watchdog, binding,&max,&buffer); if (n!=4) { skynet_error(ctx, "Invalid gate parm %s",parm); return 1; } char * portstr = strchr(binding,':'); uint32_t addr = INADDR_ANY; if (portstr == NULL) { port = strtol(binding, NULL, 10); if (port <= 0) { skynet_error(ctx, "Invalid gate address %s",parm); return 1; } } else { port = strtol(portstr + 1, NULL, 10); if (port <= 0) { skynet_error(ctx, "Invalid gate address %s",parm); return 1; } portstr[0] = '\0'; addr=inet_addr(binding); } struct mread_pool * pool = mread_create(addr, port, max, buffer); if (pool == NULL) { skynet_error(ctx, "Create gate %s failed",parm); return 1; } if (watchdog[0] == '!') { g->watchdog = NULL; } else { g->watchdog = strdup(watchdog); } g->pool = pool; int cap = 1; while (cap < max) { cap *= 2; } g->cap = cap; g->max_connection = max; g->id_index = 0; g->agent = malloc(cap * sizeof(struct connection *)); memset(g->agent, 0, cap * sizeof(struct connection *)); g->map = malloc(max * sizeof(struct connection)); memset(g->map, 0, max * sizeof(struct connection)); int i; for (i=0;i<max;i++) { g->map[i].connection_id = i; } skynet_callback(ctx,g,_cb); return 0; }
int multicast_init(struct skynet_multicast_group *g, struct skynet_context *ctx, const char * args) { skynet_callback(ctx, g, _maincb); return 0; }