一、控制客戶端連接數
在啓動網關時,可指定當前服務的最大連接數,以避免大量用戶登錄到該服務。
啓動網關服務後,運行三個 socketclient 客戶端,結果如下:
可以看到,第三個客戶端連接成功後,被立即關閉。
二、gateserver 其他回調函數
--[[
gateserver監聽成功後,會調用此接口,可用來進行一些初始化操作。
source:請求來源地址,conf:開啓 gateserver 的參數表(端口,連接數,是否延遲
--]]
function handler.open(source, conf)
end
--[[
當一個連接異常(通常意味着斷開),會調用此接口。
msg:錯誤信息(通常用於 log 輸出)。
]]--
function handler.error(fd, msg)
end
--當 fd 上待發送的數據累積超過 1M 字節後,將回調這個方法。
function handler.warning(fd, size)
end
mygateserver.lua
local skynet = require "skynet"
local gateserver = require "snax.gateserver"
local netpack = require "skynet.netpack"
local handler = {}
--當一個客戶端鏈接進來,gateserver自動處理鏈接,並且調用該函數
function handler.connect(fd, ipaddr)
skynet.error("ipaddr:",ipaddr,"fd:",fd,"connect")
gateserver.openclient(fd)
end
--當一個客戶端斷開鏈接後調用該函數
function handler.disconnect(fd)
skynet.error("fd:", fd, "disconnect")
end
--接收數據
function handler.message(fd, msg, sz)
skynet.error("recv message from fd:", fd)
--把 handler.message 方法收到的 msg,sz 轉換成一個 lua string,並釋放 msg 佔用的 C 內存。
skynet.error(netpack.tostring(msg, sz))
end
--如果報錯就關閉該套接字
function handler.error(fd, msg)
gateserver.closeclient(fd)
end
--fd中待發送數據超過1M時調用該函數,可以不處理
function handler.warning(fd, size)
skynet.skynet("warning fd=", fd , "unsent data over 1M")
end
--一旦gateserver打開監聽成功後就會調用該接口
--testmygateserver.lua通過給mygateserver.lua發送lua消息open觸發該函數調用
function handler.open(source, conf)
skynet.error("open by ", skynet.address(source))
skynet.error("listen on", conf.port)
skynet.error("client max", conf.maxclient)
skynet.error("nodelay", conf.nodelay)
end
gateserver.start(handler)
測試:
三、向 gateserver 發送lua消息
gateserver 不僅能接收 socket 消息,還能接收 skynet lua 消息,並且 gateserver 對 lua 消息註冊函數進行了封裝,只需提供 handler.command 回調函數即可,而不需要我們自己調用 skynet.dispatch 來註冊。
3.1、在 mygateserver.lua 中增加以下部分:
local CMD = {}
function CMD.kick(source, fd)
skynet.error("source:", skynet.address(source), "kick fd:", fd)
gateserver.closeclient(fd)
end
function handler.command(cmd, source, ...)
local f = assert(CMD[cmd])
return f(source, ...)
end
3.2、再編寫一個給 mygateserver 發送命令的服務:kickmygateserver.lua:
local skynet = require "skynet"
local gateserver, fd= ... --必須要轉換成整形數,skynet命令行傳入的參數都是字符串
fd = tonumber(fd)
skynet.start(function()
skynet.call(gateserver, "lua", "kick", fd)
skynet.exit()
end)
這個腳本的功能是,由命令行啓動服務 kickmygateserver,並向指定的服務發送消息。
3.3、修改 main.lua,以支持用命令行啓動服務:.
local skynet = require "skynet"
--local sprotoloader = require "sprotoloader"
skynet.start(function()
skynet.error("Server start")
if not skynet.getenv "daemon" then
local console = skynet.newservice("console") -- 創建控制檯
end
local gateserver = skynet.newservice("myservice/mygateserver")
skynet.call(gateserver, "lua", "open", {
port = 8002,
maxclient = 4096,
nodelay = true,
})
skynet.error("gate server setup on", 8002)
skynet.exit()
end)
3.4、測試:
先啓動 mygateserver,然後啓動客戶端 socketclient,最後再返回 mygateserver 並輸入命令:
myservice/kickmygateserver :0000000a 3