• 已删除用户
skynet 实现分布式的Map和Talk服务
Administrator
发布于 2021-10-10 / 178 阅读 / 0 评论 / 0 点赞

skynet 实现分布式的Map和Talk服务

实现分布式的Map服务和Talk服务. Map服务自动连接到Talk服务. 本案例没有分开, 但确实可以实现分布式部署.

Client1  ═╗
Client2  ═╩═  Map1  ═╦═  Talk
Client3  ═══  Map2  ═╝

#examples/DEconfig

include "config.path"

-- preload = "./examples/preload.lua"	-- run preload.lua before every lua service run
-- 必须配置
thread = 8                              -- 启用多少个工作线程
cpath = "./cservice/?.so"               -- 用C编写的服务模块的位置
bootstrap = "snlua bootstrap"           -- (固定)启动的第一个服务

-- bootstrap 配置项
start = "DEmain"                        -- 主服务入口
harbor = 0                              -- (固定)不适应主从节点

-- lua 配置项(暂时固定)
lualoader = "./lualib/loader.lua"
luaservice = "./service/?.lua;".."./test/?.lua;".."./examples/?.lua;".."./test/?/init.lua"
lua_path = "./lualib/?.lua;".."./lualib/?/init.lua"
lua_cpath = "./luaclib/?.so"

-- 后台模式
-- deamon = "./skynet.pid"
-- logger = "./userlog"

#examples/DEmain

local skynet = require "skynet"

skynet.start(function()
    local map1 = skynet.newservice("DEmap")
    local map2 = skynet.newservice("DEmap")
    local talk = skynet.newservice("DEtalk")


    skynet.send(map1, "lua", "start", 8001, "127.0.0.1", 8888)
    skynet.send(map2, "lua", "start", 8002, "127.0.0.1", 8888)
    skynet.send(talk, "lua", "start", 8888)
    skynet.exit()
end)

#examples/DEmap

local skynet = require "skynet"
local socket = require "skynet.socket"
 
local CMD = {}          -- 服务CMD
local clientCMD = {}    -- 客户端CMD

local clients = {}          -- 客户端连接

local clientsPoint = {}     -- 客户端位置

local talkServer
 

-- 服务开始
skynet.start(function()
    skynet.dispatch("lua", function(session, source, cmd, ...)
        local f = assert(CMD[cmd])
        f(source, ...)
    end)
end)


-- 启动服务
function CMD.start(source, port, talkIp, talkPort)
    local listenfd = socket.listen("0.0.0.0", port)
    socket.start(listenfd, CMD.connect)     -- 监听 listenfd
    skynet.fork(CMD.listentalk, talkIp, talkPort)   -- 执行 listentalk 指令
end

-- 当服务器连接时
function CMD.connect(fd, addr)
    -- 启动连接
    print(fd.." connected addr:"..addr)
    socket.start(fd)

    -- 初始化客户端
    clients[fd] = {}
    clientsPoint[fd] = {0, 0}

    -- 消息处理
    while true do
        local readdata = socket.read(fd)

        -- 正常接受
        if readdata ~= nil then
            local func

            if readdata == false then return end        -- 客户端断开连接时会向服务器发送 布尔类型 false  此时直接 return
            for cmd in readdata:gmatch("%w+") do
                func = cmd
                clientCMD[#clientCMD + 1] = cmd
            end

            if clientCMD[func] ~= nil then
                skynet.fork(clientCMD[func], fd)
            else
                socket.write(talkServer, readdata)
            end
        -- 断开连接
        else
            clientCMD.quit(fd)
        end
    end
end

function CMD.listentalk(ip, port)
    talkServer = socket.open(ip, port)
    
    while true do
        local readdata = socket.read(talkServer)

        if readdata ~= nil then
            for i, _ in pairs(clients) do
                socket.write(i, readdata)
            end
        end
    end
end

function clientCMD.left(fd)
    clientsPoint[fd][1] = clientsPoint[fd][1] - 1
    clientCMD.showMove(fd)
end

function clientCMD.right(fd)
    clientsPoint[fd][1] = clientsPoint[fd][1] + 1
    clientCMD.showMove(fd)
end

function clientCMD.up(fd)
    clientsPoint[fd][2] = clientsPoint[fd][2] + 1
    clientCMD.showMove(fd)
end

function clientCMD.down(fd)
    clientsPoint[fd][2] = clientsPoint[fd][2] - 1
    clientCMD.showMove(fd)
end

function clientCMD.showMove(fd)
    for i, _ in pairs(clients) do -- 广播
        socket.write(i, "client: "..fd.." Point is: X "..clientsPoint[fd][1].." Y "..clientsPoint[fd][2].."\n")
    end
end

function clientCMD.quit(fd)
    if clients[fd] ~= nil then
        print(fd.."close ")
        socket.close(fd)
        clients[fd] = nil
    end
end

function clientCMD.exit(fd)
    clientCMD.quit(fd)
end

#examples/DEtalk

local skynet = require "skynet"
local socket = require "skynet.socket"
 
local CMD = {}
local clients = {}
 
skynet.start(function()
    skynet.dispatch("lua", function(session, source, cmd, ...)
        local f = assert(CMD[cmd])
        f(source, ...)
    end)
end)
 
function CMD.start(source, port)
    local listenfd = socket.listen("0.0.0.0", port)
    socket.start(listenfd, connect)
end

function connect(fd, addr)
    -- 启动连接
    print(fd.." connected addr:"..addr)
    socket.start(fd)
    clients[fd] = {}
    -- 消息处理
    while true do
        local readdata = socket.read(fd)
        -- 正常接受
        if readdata ~= nil then
            for i, _ in pairs(clients) do -- 广播
                socket.write(i, readdata)
            end
        -- 断开连接
        else
            print(fd.."close ")
            socket.close(fd)
            clients[fd] = nil
        end
    end
end