skynet:網關服務 二

一、控制客戶端連接數

在啓動網關時,可指定當前服務的最大連接數,以避免大量用戶登錄到該服務。
在這裏插入圖片描述
啓動網關服務後,運行三個 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

在這裏插入圖片描述
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章