【Skynet】开始创建服务的代码流程
【Skynet】开始创建服务的流程
参考大神链接:
GitHub wiki LuaAPI
Githu wiki APIList
skynet 创建 lua 服务流程
探索skynet(二):skynet如何启动一个服务
一、skynet 中 main 的 start()
->main.lua
skynet.start(function()...newservice()
...end)
–> [ skynet_start.c ]
void
skynet_start(struct skynet_config * config) {....bootstrap(ctx, config->bootstrap); // 启动bootstrap服务...
}
一般默认,config->bootstrap项就是snlua bootstrap
二、newservice() 创建一个服务
–> [ skynet.lua ] – .launcher 一个服务
function skynet.newservice(name, ...)return skynet.call(".launcher", "lua" , "LAUNCH", "snlua", name, ...)
end
–> [ bootstrap.lua入口函数 ]
local launcher = assert(skynet.launch("snlua","launcher"))
skynet.name(".launcher", launcher)
–> [ manager.lua ]
local c = require "skynet.core"
function skynet.launch(...)local addr = c.command("LAUNCH", table.concat({...}," ")).....
–> [ lua_skynet.c ]
lcommand(lua_State *L) {.....result = skynet_command(context, cmd, parm); // cmd应该是LAUNCH , parm应该是 snlua launcher
}
–> [ skynet_server.c ]
(1)skynet_command -》cmd_launch
static struct command_func cmd_funcs[] = {{ "LAUNCH", cmd_launch },...{ NULL, NULL },
};const char *
skynet_command(struct skynet_context * context, const char * cmd , const char * param) {struct command_func * method = &cmd_funcs[0];while(method->name) {if (strcmp(cmd, method->name) == 0) {return method->func(context, param);}++method;}return NULL;
}
(2)进入 cmd_launch
static const char *
cmd_launch(struct skynet_context * context, const char * param) {size_t sz = strlen(param);char tmp[sz+1];strcpy(tmp,param);char * args = tmp;char * mod = strsep(&args, " \t\r\n");args = strsep(&args, "\r\n");struct skynet_context * inst = skynet_context_new(mod,args);if (inst == NULL) {return NULL;} else {id_to_hex(context->result, inst->handle);return context->result;}
}
(3)skynet_context_new (mod,args);
mod是snlua,args是“snlua launcher”,根据这个参数构造一个skynet_context 出来
struct skynet_context *
skynet_context_new(const char * name, const char *param) {struct skynet_module * mod = skynet_module_query(name); //① 获得snlua模块..... // 创建消息队列等等void *inst = skynet_module_instance_create(mod); // ② 创建服务....int r = skynet_module_instance_init(mod, inst, ctx, param); // ③ 初始化snlua...
}
–> service.snlua.c
先看一下结构
struct snlua {lua_State * L;struct skynet_context * ctx;size_t mem;size_t mem_report;size_t mem_limit;
};
语句①:获得snlua模块创建实例 snlua_create
struct snlua *
snlua_create(void) {struct snlua * l = skynet_malloc(sizeof(*l));memset(l,0,sizeof(*l));l->mem_report = MEMORY_WARNING_REPORT;l->mem_limit = 0;l->L = lua_newstate(lalloc, l);return l;
}
语句③:初始化snlua 其实就是 snlua_init
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 messageskynet_send(ctx, 0, handle_id, PTYPE_TAG_DONTCOPY,0, tmp, sz);return 0;
}
设置了当前模块的callback为 launch_cb,之后skynet_send消息,将由launch_cb处理
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); //回调给lua层if (err) {skynet_command(context, "EXIT", NULL);}return 0;
}
launch_cb重置了服务的回调callback ,调用init_cb
static int
init_cb(struct snlua *l, struct skynet_context *ctx, const char * args, size_t sz) {.... // 设置各种路径、栈数据const char * loader = optstring(ctx, "lualoader", "./lualib/loader.lua");int r = luaL_loadfile(L,loader);if (r != LUA_OK) {skynet_error(ctx, "Can't load %s : %s", loader, lua_tostring(L, -1));report_launcher_error(ctx);return 1;}lua_pushlstring(L, args, sz);r = lua_pcall(L,1,0,1); // 回调给lua层....
}
–> skynet.lua
function skynet.start(start_func)c.callback(skynet.dispatch_message) //回调信息返回在这skynet.timeout(0, function()skynet.init_service(start_func)end)
end
即 启动了这个服务,即,这个服务挂载到消息队列(skynet_context的mq)里面 等待 消息的处理。
【Skynet】开始创建服务的代码流程相关推荐
- 安卓应用安全指南 4.4.1 创建/使用服务 示例代码
4.4.1 创建/使用服务 示例代码 原书:Android Application Secure Design/Secure Coding Guidebook 译者:飞龙 协议:CC BY-NC-SA ...
- SAP MM ML81N为采购订单创建服务接收单,报错- No matching PO items selected -
SAP MM ML81N为采购订单创建服务接收单,报错- No matching PO items selected - SAP里的服务采购流程跟有形的实物采购流程并不相同.除了在采购单据上的差异以外 ...
- Netty实战 IM即时通讯系统(四)服务端启动流程
## Netty实战 IM即时通讯系统(四)服务端启动流程 零. 目录 IM系统简介 Netty 简介 Netty 环境配置 服务端启动流程 实战: 客户端和服务端双向通信 数据传输载体ByteBuf ...
- 《netty入门与实战》笔记-02:服务端启动流程
为什么80%的码农都做不了架构师?>>> 1.服务端启动流程 这一小节,我们来学习一下如何使用 Netty 来启动一个服务端应用程序,以下是服务端启动的一个非常精简的 Demo ...
- 服务端_说说Netty服务端启动流程
点击上方☝SpringForAll社区 轻松关注!及时获取有趣有料的技术文章 本文来源:http://yeming.me/2016/03/12/netty1/ netty服务端代码分析 服务端启动配置 ...
- Netty 源码解析系列-服务端启动流程解析
netty源码解析系列 Netty 源码解析系列-服务端启动流程解析 Netty 源码解析系列-客户端连接接入及读I/O解析 五分钟就能看懂pipeline模型 -Netty 源码解析 1.服务端启动 ...
- 基于skynet设计游戏服务端框架
skynet并不是一个开箱即用的服务端框架,游戏后端在开展业务时,需要根据自身业务特点,合理设计相应的服务端框架.在这里我根据自身的设计目标,写下各方面的选择与取舍.对于小型企业来说,一些商业化的软件 ...
- Android 中的WiFi学习笔记(转载)----WIFI启动 代码流程走读---网络连接流程
Android的WiFi 我们通常看到WiFi的守护进程wpa_supplicant在我们的ps的进程列表中,这个就是我们的wifi守护进程.wpa_supplicant在external/wpa_s ...
- Eboot代码流程 [转]
Eboot代码流程 [转] Eboot代码流程 ----by nasiry ...
最新文章
- python使用正則表達式
- 内存泄漏_内存泄漏–测量频率和严重性
- 实现根据条件删除_Vue源码解析,keep-alive是如何实现缓存的?
- 字符串中最长无重复子串(O(n))
- Spine学习六 - 碰撞检测
- JVM学习笔记二:JVM参数
- HttpHandler和HttpModule 心得介绍
- [前缀和][dp] Jzoj P5873 小p的属性
- python把某列改为日期格式_如何更改整列的日期格式?
- 第八届“图灵杯”NEUQ-ACM程序设计竞赛个人赛——J题 这是一题简单的模拟
- 【李宏毅2020 ML/DL】补充:Support Vector Machine (SVM)
- gazebo打不开world
- [数论]莫比乌斯反演入门
- 测试转开发,我都经历了什么
- mysql 批量插入数据方法_mysql大批量插入数据的4种方法示例
- 网站显示未连接上服务器,网站未连接上服务器是什么意思
- aistudio使用py检测深度学习是否训练完成并发送短信提示
- MATLAB handles 结构体及用法
- 线程间之间是如何通信的?
- 第一章 初识Java总结