123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133 |
- local socket = require "skynet.socket"
- local httpd = require "http.httpd"
- local sockethelper = require "http.sockethelper"
- local urllib = require "http.url"
- local cjson = require "cjson"
- local msgCode = require "code"
- local skynet = require "skynet"
- local mode, agent_count, server_port, command_path = ...
- if mode == "agent" then
- local httpcommand = require (command_path)
- local function response(id, response_status, response_data)
- local response_header = {["Content-Type"] = "application/text;charset=utf-8"}
- if type(response_data) == "table" then
- response_header = {["Content-Type"] = "application/json;charset=utf-8"}
- response_data = cjson.encode(response_data)
- end
- local ok, err = httpd.write_response(sockethelper.writefunc(id), response_status, response_data, response_header)
- --log.info("httpserver id:%s write response ok:%s, err:%s, response_status:%s, data_type:%s response_data:%s", id, ok, err or "nil", response_status, type(response_data), response_data)
- end
- local function format_params(id, url, method, header, body)
- local request_data = {}
- if header.host then
- request_data.host = header.host
- end
- local path, query = urllib.parse(url)
- request_data.path = path
- request_data.param = {}
- if query then
- local q = urllib.parse_query(query)
- for k, v in pairs(q) do
- request_data.param[k] = v
- end
- end
- request_data.header = {}
- for k, v in pairs(header) do
- request_data.header[k] = v
- end
- if body and body ~= "" then
- local decode_success, json_object = pcall(cjson.decode, body)
- if not decode_success then
- return msgCode.PARAMTER_ERROR
- end
- for k, v in pairs(json_object) do
- request_data.param[k] = v
- end
- end
- return msgCode.OK, request_data
- end
- local function write_error_msg(id, status)
- response(id, status, "http logic handle error")
- end
- local function handle_request(id, addr)
- local status, url, method, header, body = httpd.read_request(sockethelper.readfunc(id), 8192)
- --log.info("httpserver id:%s, addr:%s read data, status:%s, url:%s, method:%s, header:%s, body:%s", id, addr, status, url, method or "nil", header and tostring(header) or "nil", body and tostring(body) or "nil")
- if not status then
- log.info("httpserver id:%s read data not status", id)
- write_error_msg(id, 500)
- return
- end
- --[[
- if type(header) == "string" and #header > 0 then
- header = cjson.decode(header)
- end
- if type(body) == "string" and #body > 0 then
- body = cjson.decode(body)
- end
- --]]
-
- if status ~= 200 then
- log.info("httpserver id:%s status:%s ~= 200", id, status)
- write_error_msg(id, status)
- return
- end
- local code, request_data = format_params(id, url, method, header, body)
- if code ~= msgCode.OK then
- log.info("httpserver id:%s parse data error, code:%s", id, code)
- write_error_msg(id, status)
- return
- end
- --log.info("httpserver id:%s request_data:%s", id, tostring(request_data))
- local response_data = httpcommand.handle(request_data)
- response(id, status, response_data)
- end
- skynet.start(function ()
- skynet.dispatch("lua", function (_, _, id, addr)
- socket.start(id)
- -- limit request body size to 8192 (you can fill nil to unlimit)
- local is_success = safeRun(handle_request, id, addr)
- if not is_success then
- log.info("httpserver id:%s system error", id)
- pcall(write_error_msg, id, 500)
- end
- log.info("fd close id:%s", id)
- socket.close(id)
- end)
- if httpcommand.init then
- httpcommand.init()
- end
- end)
- else
- skynet.start(function ()
- local agent = {}
- for i = 1, agent_count do
- agent[i] = skynet.newservice(SERVICE_NAME, "agent", agent_count, server_port, command_path)
- end
- local id = socket.listen("0.0.0.0", server_port)
- log.info("httpserver listen web port " .. server_port)
- local balance = 1
- socket.start(id, function (id, addr)
- skynet.send(agent[balance], "lua", id, addr)
- balance = balance + 1
- if balance > #agent then
- balance = 1
- end
- end)
- end)
- end
|