Lua

Eave 2017.04.18 08:04

http, server, location, location模块中关闭lua缓存 lua_code_cache off;

-- #!/usr/bin/lua

local cjson = require("cjson")
local redis = require("resty.redis")
local os = require("os")
-- local zlib = require("zlib")

gateway_ping_hash_key = "GatewayPingHash"
host = "127.0.0.1"
port = 6379

ngx.req.read_body()
local req = ngx.req.get_body_data()

-- 判断post数据是否有gzip压缩
local encoding = ngx.req.get_headers()["Content-Encoding"]

if encoding == "gzip" then
    ngx.exec("@authxmu")
    return
--     local stream = zlib.inflate()
--     req = stream(req);
--     -- ngx.req.set_body_data(req);
end

-- req = '{"id":"KK1006A","clients":{}}'
-- 判断post数据是否为空
if req == nil then
    ngx.say("{}")
    return
end

local jsonp = cjson.decode(req)
-- 数据上报
local clients = cjson.encode(jsonp.clients)

if clients == nil or clients == "{}" or clients == "[]" then
    --连接redis
    local red = redis:new()
    red:set_timeout(1000) -- 1 sec
    local ok, err = red:connect(host, port)
    if not ok then
        -- ngx.say("failed to connect: ", err)
        return
    end

    local res = {}
    res['time'] = os.time()

    local ok, err = red:hset(gateway_ping_hash_key, jsonp.id, cjson.encode(res))
    ngx.say("{}")
    return
end

ngx.exec("@authxmu")
return

-- 连接redis
local red = redis:new()
red:set_timeout(1000) -- 1 sec
local ok, err = red:connect(host, port)
if not ok then
    -- ngx.say("failed to connect: ", err)
    return
end
ok, err = red:set_keepalive(60000, 100)

-- TEST
-- local data = {}
-- data["device_id"] = "CNGW00001"
-- data["userid"] = 1
-- data["mc_id"] = 1;
-- data["token"] = "f2cd38cc676ba4e001f53d5d7b417561"
-- data["url"] = "ILoveDengfuyu"
-- data["user_agent"] = "ILoveDengfuyu"
-- data["status"] = 1
-- data["active_time"] = 0
-- red:hset(token_hash_key, "8CBEBE62A09C", cjson.encode(data))

token_hash_key = "TokenHash_" .. jsonp.id
connection_hash_key = "ConnectionHash_" .. jsonp.id

-- 客户端认证
local res = {}
local clients = {}
for i, v in ipairs(jsonp.clients) do
    local auth = 0
    -- 将MAC地址转换为大写字母
    local mac = string.upper(v.mac)
    -- 将MAC地址中的冒号去掉
    local real_mac = string.gsub(mac, ":", "")
    local res, err = red:hget(token_hash_key, real_mac)
    -- Redis中数据存在
    if(type(res) == "string") then
        local token_info = cjson.decode(res)
        -- 验证用户Login
        if v.state == "login" then
            -- 用户token与Redis中的token一致
            if token_info.token == v.token then
                local data = {}
                data["token"] = v.token
                data["timestamp_in"] = os.time()
                data["device_id"] = gw_id
                data["userid"] = token_info.userid
                data["mc_id"] = token_info.mc_id
                data["user_mac"] = mac
                data["user_agent"] = token_info.user_agent
                data["user_ip"] = ip
                data["last_updated"] = os.time()
                data["incoming"] = 0
                data["outcoming"] = 0
                data["url"] = token_info.url
                data["status"] = 1
                data["timestamp_out"] = 0

                -- 数据放入connection中
                local ok, err = red:hset(connection_hash_key, token_info.userid, cjson.encode(data))

                -- 更新token数据
                token_info.status = 2
                token_info.active_time = os.time()
                local ok, err = red:hset(token_hash_key, real_mac, cjson.encode(token_info))
                auth = 1
            end
        -- 用户上报流量数据
        elseif v.state == "authed" then
            -- 用户token与Redis中的token一致
            if token_info.token == v.token then
                local res, err = red:hget(connection_hash_key, token_info.userid)
                -- Redis中数据存在
                if(type(res) == 'string') then
                    connection_info = cjson.decode(res)
                    -- 用户token与Redis中的token一致
                    if(connection_info.token == token_info.token) then
                        connection_info.incoming = v.incoming
                        connection_info.outcoming = v.outgoing
                        connection_info.last_updated = os.time()
                        red:hset(connection_hash_key, cjson.encode(connection_info))
                        auth = 1
                    end
                end
            end
        elseif v.state == "logout" then
            local res, err = red:hget(token_hash_key, real_mac)
            -- Redis中数据存在
            if(type(res) == "string") then
                token_info = cjson.decode(res)
                -- 用户token与Redis中的token一致
                if token_info.token == v.token then
                    red:hdel(token_hash_key, real_mac);
                    local res, err = red:hget(connection_hash_key, token_info.userid)
                    -- Redis中数据存在
                    if(type(res) == "string") then
                        connection_info = cjson.decode(res)
                        -- 用户token与Redis中的token一致
                        if(connection_info.token == v.token) then
                            red:hdel(connection_hash_key, token_info.userid)
                        end
                    end
                end
            end
        end
    end
    local data = {}
    data["mac"] = v.mac
    data["auth"] = auth
    data["code"] = auth
    table.insert(clients, data)
end
local ok, err = red:close()
res["clients"] = clients

-- 设置响应头信息
ngx.header["Content-Type"] = "application/json;charset=UTF-8"
-- 内容输出
ngx.say(cjson.encode(res))
-- 设置响应状态码
ngx.exit(ngx.HTTP_OK)