Lua获取网络时间
作者:ani_di
版权所有,转载务必保留此链接 http://blog.csdn.net/ani_di
Lua获取网络时间
网络授时服务是一些网络上的时间服务器提供的时间,一般用于本地时钟同步。 授时服务有很多种,一般我们选择RFC-868。这个协议的工作流程是:(S代表Server,C代表Client)
S: 检测端口37
U: 连接到端口37
S: 以32位二进制数发送时间
U: 接收时间
U: 关闭连接
S: 关闭连接
协议非常简单,用TCP连接上后,服务器直接把时间发送回来。发送的是从1900年1月1日午夜到现在的秒数。
使用luasocket
实现的方案有很多种,Lua不一定是最简单的,选择只是出于个人兴趣。直接上代码吧
– Network Time Protocal
– Author: ani_di
源码:
package.cpath = package.cpath .. ';D:\\tools\\Lua\\5.1\\clibs\\?.dll;?.dll'
local socket = require "socket.core"
server_ip = { ...
微博API发送微博
使用微博的API和SDK的其中的关键一步是取得token. 而取得token是需要通过oauth2认证才可以得到。
下面是一段取得token的代码逻辑:
APP_KEY ='012345678'
APP_SECRET = '01234567891011121314151617181920'
CALL_BACK= 'http://www.lua.ren/callback'
client = weibo.APIClient(APP_KEY, APP_SECRET, CALL_BACK)
auth_url = client.get_authorize_url()
login_url = 'https://api.weibo.com/oauth2/authorize'
params = urllib.urlencode({'action' : 'submit','response_type' : 'code','redirect_uri' : CALL_BACK,'client_id' : APP_KEY,'userId' : 'userid','passwd' : 'passwo ...
TMUX最常用操作命令
作者:糖果
一般情况下,当你用SSH链接VPS,然后关掉terminal的操作窗口时,所有的当前操作都结束了。而如果用TMUX,当前正在运行的非后台操作会话还会存在,下面是TMUX最常用的操作了。
1.创建新会话
tmux new -s candylab
2.选择新会话
tmux attach -t candylab
3.显示会话列表
tmux ls
4.翻页
Ctrl + b + (PageUp PageDown)
5.退出当前tmux会话
Ctrl + b + d是退出当前会话,但是用tmux ls盾,这个会话,还是会存在的,如果exit命令,当前的tmux会话就彻底结束了,tmux ls中也少了当前的会话。
6.上下分屏
Ctrl + b + %
7.左右分屏
Ctrl + b + “
8.重命名当前会话
Ctrl + b + $ 重命名session
糖果实验室
1.花园黄金牧场婴儿奶粉1段新生儿0-6个月宝宝100g小罐试用
2.屁屁乐护臀霜60g 婴儿护臀膏 新生儿护臀霜PP乐 针对宝宝PP护理
3.加菲猫 婴儿橄榄油 宝宝润肤油新生儿BB油 保湿抚触按 ...
Lua的Require理解
作者:ms2008
整理编辑:糖果
在 lua 中加载的其他文件的代码,通常可以使用 dofile、loadfile、require 函数等来完成。其中 dofile 每次加载都要编译执行,效率比较低,所以不推荐使用;同样 loadfile 虽然只需编译一次,但是并没有把结果缓存到 lua vm 中;因而,我们这里总是推荐使用第三种方式 require。
require 能够避免多次重复加载模块,一个模块被加载后会被缓存到 pacakge.loaded。 如果需要重新加载模块,可以清理 package.loaded.test = nil。
需要注意的是,require() 函数并没有使用全局变量,它是在 package.loaded 表里缓存已经加载的 Lua module 的。而 package.loaded 是挂载在 Lua VM 的 registry 表里的,不同于全局变量的环境表。
另外:
Lua module 不一定是 table,也可以是 function,只是 table 比较常见罢了。function 的一个例子是 LuaJIT 2.1 的 require(“table ...
Tail Call 到底有啥用?
作者:ms2008
整理编辑:糖果
在聊今天这个话题之前,我们需要知道什么叫 tail call。先来看下,lua 程序设计是怎么定义的:
尾调用是一种类似在函数结尾的 goto 调用,当函数最后一个动作是调用另外一个函数时,我们称这种调用尾调用。例如:
function f(x)
return g(x)
end
g 的调用是尾调用。
例子中 f 调用 g 后不会再做任何事情,这种情况下当被调用函数 g 结束时程序不需要返回到调用者 f;所以尾调用之后程序不需要在栈中保留关于调用者的任何信息。一些编译器比如 Lua 解释器利用这种特性在处理尾调用时不使用额外的栈,我们称这种语言支持正确的尾调用。
由于尾调用不需要使用栈空间,那么尾调用递归的层次可以无限制的。
是不是有些迷糊?那我继续来解释下「详情可以参考廖雪峰的blog」:
我们知道在函数内部,可以调用其他函数。如果一个函数在内部调用自身本身,这个函数就是递归函数。递归函数的优点是定义简单,逻辑清晰。但是使用递归函数有个要命的缺点就是需要注意防止栈溢出!
在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调 ...
OpenResty 中的连接池
OpenResty 中的连接池
作者:ms2008
编辑整理:糖果
注:set_keepalive 和 close 互斥(一个 socket 对象不能执行多次 setkeepalive 操作,会报:连接已关闭)
连接池的大小是对每一个 nginx worker 而言的。如果有 N 个 worker,最多就会有 N * pool_size 个连接。比如设置 keepalive=100,开始启动时候是0连接来一个请求,获取一个 socket(空闲的),完成请求后,socket<100 时候,就把 socket 放到池子里。每当新请求来的时候,先去池子里面获取空闲 socket,如果获取不到就创建新连接,完成请求后,新连接的数量如果超过设置的 keepalive 值就不放池子里面了。当并发连接数大大超过了连接池的容量,就会产生很多的短连接,此时就应该增加连接池的大小。
连接池常见问题及调试方法:
在测试时配置了 lua_code_cache off,即禁用了 Lua 代码缓存,此时连接池的生命期是每请求的,因为 cosocket 连接池是在 Lua VM 里面分配的,而在禁用 Lua ...
OpenResty China的登陆处理与发贴限制
作者:糖果
Openresty China是饭总之前创建,现在由我来维护一个线上的版本。最开始的时候,对于orchina.org的用户来说的,是有三天内不能发贴的限制的,但之后我们想用一个用户激活的标志来控制是否允许用户发帖,从路由和视图几角度来看,如下:
1.Login登陆模块。
Openresty China用的是Lor框架,封装出了Session功能:
/app/routes/auth.lua 这个文件中,集中处理了登陆登出的功能, 在登陆时,在session保存了一个变量,用于之后是否可发贴的判断逻辑。
auth_router:post("/login", function(req, res, next)
local username = req.body.username
local password = req.body.password
if not username or not password or username == "" or password == "" then
return res:json({
...
Python的命令行解析工具OptParse
作者:糖果
无论是用C语言,还是用Java,有时都会写一些命令行的工具,解析用户在命令输入的参数,而Python有自己特色的命令行参数解析库,就是optparse。hpfeed-cli的源码就是用optparse来解析命令行参数的,hpfeed是给威胁地图发送威胁数据的,使用的是hpfeed协议,hpfeed-cli是一个在terminal中直接运行的命令行程序,有着非常复杂的参数输入。
import sys
import optparse
import datetime
import logging
import string
def main(opts, action, pubdata=None):
outfd = None
print action
print data
print options
return 0
def opts():
usage = "usage: %prog -i ident -s secret --host host -p port -c channel1 [-c channel2, ...] &l ...
Lua判断空表的正确姿势
作者:ms2008
编辑:糖果
if t == {} then
这样的结果就是 t == {} 永远返回 false,是一个逻辑错误。因为这里比较的是 table t 和一个匿名 table 的内存地址。
if table.maxn(t) == 0 then
这样做也不保险,除非 table 的 key 都是数字,而没有 hash 部分。
if next(t) == nil then
next 其实就是 pairs 遍历 table 时用来取下一个内容的函数。在项目的 module 中最好封装一下,免得 module 本地也有 next 函数。封装后判断的 lua table 是否为空的函数如下:
function table_is_empty(t)
return _G.next(t) == nil
end
糖果实验室编辑整理
VIM打开中文乱码
今天在coding下用vim,打开含有中文的文件乱码,找了一下解决方案。
在.vimrc中,加入下面的文件编码指定:
set fileencodings=utf-8,ucs-bom,gb18030,gbk,gb2312,cp936
set termencoding=utf-8
set encoding=utf-8


