实现分布式的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