HomeServer/Server/Lib/Http/HttpSocket.lua
2024-11-20 15:41:37 +08:00

159 lines
4.7 KiB
Lua
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

local skynet = require "skynet"
local socket = require "skynet.socket"
local httpd = require "http.httpd"
local sockethelper = require "http.sockethelper"
local urllib = require "http.url"
local serverId = tonumber(skynet.getenv "serverId")
local log = require "Log"
local table = table
local string = string
local mode, protocol = ...
protocol = protocol or "http"
if mode == "agent" then
local function response(id, write, ...)
local headers =
{
['Access-Control-Allow-Origin'] = '*', -- 这里写允许访问的域名就可以了,允许所有人访问的话就写*
['Access-Control-Allow-Credentials'] = true,
}
local code, tmp = ...
local ok, err = httpd.write_response(sockethelper.writefunc(id),code,tmp,headers)
if not ok then
skynet.error(string.format("fd = %d, %s", id, err))
end
end
local SSLCTX_SERVER = nil
local function gen_interface(protocol, fd)
if protocol == "http" then
return {
init = nil,
close = nil,
read = sockethelper.readfunc(fd),
write = sockethelper.writefunc(fd),
}
elseif protocol == "https" then
local tls = require "http.tlshelper"
if not SSLCTX_SERVER then
SSLCTX_SERVER = tls.newctx()
-- gen cert and key
-- openssl req -x509 -newkey rsa:2048 -days 3650 -nodes -keyout server-key.pem -out server-cert.pem
local certfile = skynet.getenv("certfile") or "./server-cert.pem"
local keyfile = skynet.getenv("keyfile") or "./server-key.pem"
print(certfile, keyfile)
SSLCTX_SERVER:set_cert(certfile, keyfile)
end
local tls_ctx = tls.newtls("server", SSLCTX_SERVER)
return {
init = tls.init_responsefunc(fd, tls_ctx),
close = tls.closefunc(tls_ctx),
read = tls.readfunc(fd, tls_ctx),
write = tls.writefunc(fd, tls_ctx),
}
else
error(string.format("Invalid protocol: %s", protocol))
end
end
skynet.start(function()
skynet.dispatch("lua", function (_,_,id,addr)
socket.start(id)
local interface = gen_interface(protocol, id)
if interface.init then
interface.init()
end
-- limit request body size to 8192 (you can pass nil to unlimit)
local code, url, method, header, body = httpd.read_request(interface.read, 8192)
log.info("HttpServer收到消息",addr,code, url, body)
--每次只找最后参数
local str = url
local subStr = "/"
local lastIndex = string.find(str, subStr) -- 返回第一次出现subStr的索引值
while true do
local nextIndex = string.find(str, subStr, lastIndex + 1) -- 从上一次结果之后开始查找
if not nextIndex then break end -- 如果没有再找到则退出循环
lastIndex = nextIndex -- 更新lastIndex为当前找到的索引值
end
url = string.sub(str , lastIndex + 1 , #str)
log.debug("HttpServer截取Url后的值" , url )
if code then
if code ~= 200 then
response(id, interface.write, code)
else
local RecvMsg = {}
--把消息转向主服务器
local s2cData,retLen = skynet.call("StartServer", "lua","HttpMsg",id ,url , body , addr, header)
if s2cData then
--if "metrics" == url or "health" == url then
-- RecvMsg = s2cData
--else
table.insert(RecvMsg,s2cData.."\n")
RecvMsg =table.concat(RecvMsg,"\n")
--end
end
response(id, interface.write, code, RecvMsg )
end
else
if url == sockethelper.socket_error then
skynet.error("socket closed")
else
skynet.error(url)
end
end
--该接口传输大量数据时有可能未传完socket就关闭了对其进行sleep 1000ms 后再关闭socket。
if "QueryClusterInfo" == url then
skynet.sleep(100)
end
log.info("关闭SOCKET", id , url)
socket.close(id)
if interface.close then
interface.close()
end
end)
end)
else
local agent = {}
local balance = 1
skynet.start(function()
skynet.dispatch("lua", function (_,_, cmd, ...)
if "Post" == cmd then
log.info("cmd",cmd ,...)
local id , interface, code,tmp = ...
if "write" == interface then
response(id, interface.write, code, tmp)
end
end
end)
end)
local serverIp , serverPort = ...
skynet.start(function()
local protocol = "http"
--游戏服只需要5个 http agent就够
local agentCount = 100
if serverId >= 100 then
agentCount = 5
end
for i= 1, agentCount do
agent[i] = skynet.newservice(SERVICE_NAME, "agent", protocol)
end
local id = socket.listen( serverIp , serverPort)
skynet.error(string.format("服务器 %s 监听端口 %s 协议 %s", serverIp ,serverPort , protocol))
socket.start(id , function(id, addr)
skynet.error(string.format("%s connected, pass it to index %d agent :%08x", addr,balance, agent[balance]))
skynet.send(agent[balance], "lua", id , addr )
balance = balance + 1
if balance > #agent then
balance = 1
end
end)
end)
end