Hello!
2014-05-14 9:17 GMT-07:00 小冶:
> 我试了一下,发现前者好像与当前请求共用一个ngx.ctx,后者则不是。
后者也是。不是就是 bug 了。
> 我有一个需求,场景可以近似为开房间聊天,客户端用websocket连上来后,通过redis互转消息(因为每个websocket只能在自己的request里收发)
> 现在希望第一个用户在创建房间后,在服务器跑一个后台逻辑,如聊天过滤,或者超时踢人之类。
超时保护应该尽量直接使用 websocket 的超时设置,见
https://github.com/openresty/lua-resty-websocket#set_timeout
注意,无论是 croutine.create() 创建的常规的 Lua coroutine 还是由 ngx.thread.spawn
创建的“轻量级线程”,都是和创建它们的请求绑定的。如果你要创建和当前请求分离开的后台逻辑,应当使用
ngx.timer.at().
你可以参考 lua-resty-upstream-healthcheck 库的实现:
https://github.com/openresty/lua-resty-upstream-healthcheck#readme
关于 ngx.thread.spawn() 创建的“轻线程”的行为细节,可以参考其官方文档:
https://github.com/openresty/lua-nginx-module#ngxthreadspawn
简单地说,“轻线程”是自动往前不断(异步地)执行的,由 ngx_lua 的轻线程调度器自动调度,而不用你自己一次一次地 resume. 而
coroutine.create() 创建的常规协程并不会自动往前执行,而需要你自己通过 coroutine.resume()
同步地调用。关于后者的细节可以参见 Lua 5.1 官方手册中的对应章节:
http://www.lua.org/manual/5.1/manual.html#2.11
> 我想把这个逻辑写成一个死循环函数跑在协程里,应该用ngx.thread.spawn跑还是普通的coroutine.create呢?
> 潜在的要求是:
> 1、虽然这个协程是第一个用户创建的,但是当第一个用户退出(websocket断开)后,它还应该正常在跑
> 2、需要有一个终结它的地方,即当房间里所有用户都退出后,是不是应该让它自己去检测这个条件然后退出循环?还有别的外部结束办法吗
>
建议实现为延绵不绝的定时器(可以由 init_worker_by_lua 发起第一个 timer)。尽量不要让单个处理程序(包括 timer
回调)本身运行太久。还是参考上面提及的 lua-resty-upstream-healthcheck 库的实现。
Regards,
-agentzh