免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 8756 | 回复: 11
打印 上一主题 下一主题

[其他] 【 代码分享:如何正确的将lua嵌入到c服务端 (BUG已修复,欢迎参考)】 [复制链接]

论坛徽章:
4
水瓶座
日期:2013-09-06 12:27:30摩羯座
日期:2013-09-28 14:07:46处女座
日期:2013-10-24 14:25:01酉鸡
日期:2014-04-07 11:54:15
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-04-15 13:44 |只看该作者 |倒序浏览
本帖最后由 linux_c_py_php 于 2013-04-17 13:34 编辑

lua_frame.tar.gz (11.86 KB, 下载次数: 159)

项目说明:
    以c编写基于epoll的单线程网络服务端,嵌入lua以便支持脚本编写请求处理逻辑,并且完美的支持了yield。

工作原理为:
      一,c服务端框架:
           1) 一个session对应一个coroutine,所有session共享同一个main thread。coroutine的引用计数在main thread的一个table中维持, 即fd->coroutine的映射。
        2)负责网络I/O,负责request的解析并将其加入到所属session的request-queue尾部。根据session(连接,会话)的request-queue是否为空并处于coroutine yield的状态(wait_req标记位)决定是否需要调用lua_resume唤醒lua处理request-queue。
        3)每个session都有独立的定时器检查coroutine状态,如果coroutine因为语法等任何错误而死亡,能够及时的探测并踢除session的连接。
     
    二,lua扩展框架中:
           1)用户编写main.lua,填写业务回调callback函数, 之后调用start_consume即进入了请求处理循环。
        2)start_consume将检查request queue来获取一个request,如果没有request则yield挂起等待c框架唤醒,否则将request传给用户callback进行处理。
           3)并提供给了用户一些lua api进行编程, 现在只提供了一个发送报文的接口, 后续会给出定时器, 连接/读/写 等异步编程接口.
         
不便之处:
    1,由于c服务端只有一个main thread(全局lua_State),每个session都是在main thread创建的coroutine thread上执行的,所以是通过设置coroutine.resume(callback)
中的callback的_ENV(第一个upvalue)实现每个coroutine都拥有独立的session全局变量。结果就是,在实现lua module的时候,由于require继承全局环境而非callback的环境, 导致在开发时不得不将session变量从main.lua(只有main.lua的_ENV里可见session)向下传递。(@_@,但愿你看代码的时候能够体会)

其他说明:
      为了体现lua给c带来了什么好处, 我开发了一个lua api叫做block_alarm,其作用是阻塞N毫秒之后执行回调函数,这对于lua开发者来说是看似阻塞的,但对于c服务端框架来说是完全异步的,并不会阻塞其他连接的处理。

使用示例:
  1. sapi = require('sapi')
  2. require('os')

  3. function cb(sess, req)
  4.     first = "curtime=" .. tostring(os.time()) .. " req=" .. req
  5.     sapi.write_response(sess, first)
  6.     function alarm_cb(arg)
  7.         second = "curtime=" .. tostring(os.time()) .. " res=" .. req
  8.         sapi.write_response(sess, second)
  9.     end
  10.     sapi.block_alarm(sess, 4000, alarm_cb, req)                                                                                       
  11. end

  12. sapi.start_consume(session, cb)
复制代码
sapi是我提供的基础lua module,用于和c服务端进行交互,一共就3个接口,大家看一下:
  1. module('sapi', package.seeall) --session api

  2. local capi = require('capi')

  3. --get a request from session->reqs if not empty,
  4. --otherwise it will do yield.
  5. --you have to notice that we are already in coroutine here

  6. function get_req(session)
  7.     req = capi._get_req(session)
  8.     while req == nil do
  9.         coroutine.yield()
  10.         req = capi._get_req(session)
  11.     end
  12.     return req
  13. end

  14. function write_response(session, content)
  15.     return capi._write_response(session, content)
  16. end

  17. function block_alarm(session, timeout, callback, arg)
  18.     capi._block_alarm(session, timeout)                                                                                               
  19.     coroutine.yield()
  20.     callback(arg)
  21. end

  22. function start_consume(session, cb)
  23.     while true do
  24.         req = get_req(session)
  25.         cb(session, req)
  26.     end
  27. end
复制代码
欢迎lua志同道合的朋友一起研究lua,并给该项目的设计思路中错误或者不足的地方给予指正。

论坛徽章:
4
水瓶座
日期:2013-09-06 12:27:30摩羯座
日期:2013-09-28 14:07:46处女座
日期:2013-10-24 14:25:01酉鸡
日期:2014-04-07 11:54:15
2 [报告]
发表于 2013-04-15 13:59 |只看该作者
本帖最后由 linux_c_py_php 于 2013-04-17 13:36 编辑


2013年04月17日:

1,修复了net_free中调用net_free_session的实现bug。
2,修复了sio_timer中long long截断int引起的定时器bug。

论坛徽章:
4
水瓶座
日期:2013-09-06 12:27:30摩羯座
日期:2013-09-28 14:07:46处女座
日期:2013-10-24 14:25:01酉鸡
日期:2014-04-07 11:54:15
3 [报告]
发表于 2013-04-15 15:44 |只看该作者
本帖最后由 linux_c_py_php 于 2013-04-15 19:38 编辑

反馈回答区:

论坛徽章:
4
水瓶座
日期:2013-09-06 12:27:30摩羯座
日期:2013-09-28 14:07:46处女座
日期:2013-10-24 14:25:01酉鸡
日期:2014-04-07 11:54:15
4 [报告]
发表于 2013-04-15 16:21 |只看该作者
本帖最后由 linux_c_py_php 于 2013-04-15 19:39 编辑

精华问题区:

论坛徽章:
4
水瓶座
日期:2013-09-06 12:27:30摩羯座
日期:2013-09-28 14:07:46处女座
日期:2013-10-24 14:25:01酉鸡
日期:2014-04-07 11:54:15
5 [报告]
发表于 2013-04-15 19:39 |只看该作者
本帖最后由 linux_c_py_php 于 2013-04-15 19:54 编辑

bug修复中。

论坛徽章:
0
6 [报告]
发表于 2013-04-15 19:45 |只看该作者
强哥,学习

论坛徽章:
4
水瓶座
日期:2013-09-06 12:27:30摩羯座
日期:2013-09-28 14:07:46处女座
日期:2013-10-24 14:25:01酉鸡
日期:2014-04-07 11:54:15
7 [报告]
发表于 2013-04-15 19:56 |只看该作者
xhb8413 发表于 2013-04-15 19:45
强哥,学习


有bug啊,哈哈,先找bug去了。

论坛徽章:
4
水瓶座
日期:2013-09-06 12:27:30摩羯座
日期:2013-09-28 14:07:46处女座
日期:2013-10-24 14:25:01酉鸡
日期:2014-04-07 11:54:15
8 [报告]
发表于 2013-04-17 13:28 |只看该作者
娃哈哈,找到bug了,是最小堆里把long long截断到int了,^_^。

论坛徽章:
4
水瓶座
日期:2013-09-06 12:27:30摩羯座
日期:2013-09-28 14:07:46处女座
日期:2013-10-24 14:25:01酉鸡
日期:2014-04-07 11:54:15
9 [报告]
发表于 2013-04-17 14:37 |只看该作者
{:3_200:}哇哈哈哈,lua代码里都没有用local,大家不要学我,啊哈哈哈

论坛徽章:
0
10 [报告]
发表于 2013-05-15 00:16 |只看该作者
最近也在研究LUA。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP