网关和客户端交互
来源:互联网 发布:天津基础网络教研平台 编辑:程序博客网 时间:2024/05/22 15:30
6.2 网关和客户端交互
需要配置网关服务器,客户端和写入与客户端通信的协议
文件目录结构如下:
(1)/test/bin/client/config/config
--集群中服务搜索路径,skynet.newservice()时搜索的路径--添加bin/client/?.lua,这个是为了找到main_client.lua--添加bin/client/service/?.lua , bin/service文件夹里存放client的服务luaservice = "./service/?.lua;./../test/bin/client/?.lua;./../test/bin/client/service/?.lua;"lualoader = "lualib/loader.lua"cpath = "./cservice/?.so"--兼容skynet1.0lua_path = "./lualib/compat10/?.lua;./lualib/?.lua;./lualib/?/?.lua"--这个是集群的IP和端口的配置文件, 放在了bin文件夹下cluster = "./../test/bin/clustername.lua"snax = "./test/?.lua"
(2)/test/bin/client/service/client.lua
package.cpath = "luaclib/?.so"package.path = "lualib/?.lua"if _VERSION ~= "Lua 5.3" then error "Use lua 5.3"end--发送请求,接收包,解析包,传送包local socket = require "client.socket"local proto = require "teach.proto"local sproto = require "sproto"local host = sproto.new(proto.s2c):host "package"local request = host:attach(sproto.new(proto.c2s)) --sproto.new(type--c2s,s2c)local fd = assert(socket.connect("127.0.0.1", 64000))local function send_package(fd, pack) --send the package local package = string.pack(">s2", pack) socket.send(fd, package)endlocal function unpack_package(text) --unpack the package local size = #text if size < 2 then return nil, text end local s = text:byte(1) * 256 + text:byte(2) if size < s+2 then return nil, text end return text:sub(3,2+s), text:sub(3+s)endlocal function recv_package(last) --receive package local result result, last = unpack_package(last) if result then return result, last end local r = socket.recv(fd) if not r then return nil, last end if r == "" then error "Server closed" end return unpack_package(last .. r)endlocal session = 0local function send_request(name, args) session = session + 1 local str = request(name, args, session) send_package(fd, str) print("Request:", session)endlocal last = ""local function print_request(name, args) print("REQUEST", name) if args then for k,v in pairs(args) do print(k,v) end endendlocal function print_response(session, args) print("RESPONSE", session) if args then for k,v in pairs(args) do print(k,v) end endendlocal function print_package(t, ...) if t == "REQUEST" then print_request(...) else assert(t == "RESPONSE") print_response(...) endendlocal function dispatch_package() while true do local v v, last = recv_package(last) if not v then break end print_package(host:dispatch(v)) endendlocal i = 0while true do dispatch_package() send_request("heartbeat",{i=i}) i = i + 1 socket.usleep(5 * 1000000)end
(3)/test/bin/client/main_client.lua
local skynet = require "skynet"local cluster = require "cluster"local snax = require "snax"skynet.start(function() cluster.open("client") skynet.newservice("client")end)
(4)/test/bin/gateway/config/config
thread = 8logger = nil--集群harbor要是0harbor = 0--集群主服务start = "main_gateway"bootstrap = "snlua bootstrap" -- The service for bootstrap--集群中服务搜索路径,skynet.newservice()时搜索的路径--添加bin/gateway/?.lua,这个是为了找到main_gateway.lua--添加bin/gateway/service/?.lua , bin/service文件夹里存放gateway的服务luaservice = "./service/?.lua;./../test/bin/gateway/?.lua;./../test/bin/gateway/service/?.lua"lualoader = "lualib/loader.lua"cpath = "./cservice/?.so"--兼容skynet1.0lua_path = "./lualib/?/?.lua;./lualib/compat10/?.lua;./lualib/?.lua;"--这个是集群的IP和端口的配置文件, 我放在了bin文件夹下cluster = "./../test/bin/clustername.lua"snax = "./test/?.lua"
(5)/test/bin/gateway/service/gateway.lua
local skynet = require "skynet"local gateserver = require "snax.gateserver"local netpack = require "netpack"local proto = require "teach.proto"local sproto = require "sproto"local driver = require "socketdriver"local sprotoloader = require "sprotoloader"local host = sprotoloader.load(1):host "package"local request = host:attach(sprotoloader.load(2))local connection = {}-- fd -> connection : { fd , client, agent , ip, mode }local handler = {}local REQUEST = {}local function request(name, args, response) local f = assert(REQUEST[name]) local r = f(args) if response then return response(r) endendfunction REQUEST.heartbeat(args) return {result = string.format("gate get hearbet %s", args.i)}endlocal function send_package(fd, pack) local package = string.pack(">s2", pack) driver.send(fd, package)endfunction handler.open(source, conf) --监听端口打开初始化,source 是请求来源地址, --conf 是开启 gate 服务的参数表 skynet.error(string.format("Gateway open source[%d]", source))endfunction handler.message(fd, msg, sz) --当一个完整的包被切分好后,message 方法被调用 if msg then local type, name, args, response = host:dispatch(msg, sz) skynet.error(string.format("type[%s], name[%s]", type, name)) for k, v in pairs(args) do skynet.error(string.format("args k[%s] v[%s]", k, v)) end if type == "REQUEST" then local ok, result = pcall(request, name, args, response) if ok then if result then return send_package(fd, result) end return nil else skynet.error(result) return nil end else assert(type == "RESPONSE") error "This example doesn't support request client" end endendfunction handler.connect(fd,addr) --fd(socket type) gateserver.openclient(fd) skynet.error(string.format("Client fd[%d] connect gateway addr[%s]", fd, addr))endfunction handler.disconnect(fd) skynet.error(string.format("Client fd[%d] disconnect gateway", fd)) gateserver.closeclient(fd) connection[fd] = nilendfunction handler.error(fd, msg) skynet.error(string.format("Gateway error fd[%d] msg[%s]", fd, msg))endfunction handler.warning(fd, size) skynet.error(string.format("Gateway warning fd[%d] size[%s]", fd, size))endlocal CMD = {} function handler.command(cmd, source, ...) --服务处理一些 skynet 内部消息,可以注册 command 方法 local f = assert(CMD[cmd]) return f(...) endgateserver.start(handler)
(6)/test/bin/gateway/service/preload.lua
local skynet = require "skynet"local sprotoparser = require "sprotoparser"local sprotoloader = require "sprotoloader"local proto = require "teach.proto"skynet.start(function() sprotoloader.save(proto.c2s, 1) sprotoloader.save(proto.s2c, 2)end)
(7)/test/bin/gateway/main_gateway.lua
local skynet = require "skynet"local cluster = require "cluster"local snax = require "snax"require "skynet.manager"local service_config = require "teach.service_config"skynet.start(function() cluster.open("gateway") skynet.uniqueservice("preload") local gateway = skynet.newservice("gateway") skynet.name(".gateway", gateway) pcall(skynet.call, gateway,"lua","open", { port = service_config["gateway_server"]["port"], maxclient =1024, nodelay = true, })end)
(8)/test/bin/clustername.lua
cluster1 = "0.0.0.0" .. ":" .. "65000"cluster2 = "0.0.0.0" .. ":" .. "65001"client = "0.0.0.0" .. ":" .. "65002"gateway = "0.0.0.0" .. ":" .. "65003"
(9)/test/bin/serverd.sh –启动脚本
killall -9 skynetgnome-terminal --geometry=80x24+20+10 -x ./skynet ./../test/bin/gateway/config/config &gnome-terminal --geometry=80x24+120+10 -x ./skynet ./../test/bin/client/config/config &
(10)关于与客户端的通信协议,文件结构如下:
把teach目录(包含proto.lua和service_config.lua)放入skynet/lualib下面
(1)/skynet/lualib/sproto.lua
local sprotoparser = require "sprotoparser"local proto = {}proto.c2s = sprotoparser.parse [[.package { type 0 : integer session 1 : integer}handshake 1 { response { msg 0 : string }}get 2 { request { what 0 : string } response { result 0 : string }}set 3 { request { what 0 : string value 1 : string }}quit 4 {}heartbeat 5 { request { i 0 : string } response { result 0 : string }}]]proto.s2c = sprotoparser.parse [[.package { type 0 : integer session 1 : integer}heartbeat 1 {}]]return proto
(2)/skynet/lualib/service_config.lua
local service_config = {}service_config["gateway_server"] = { host = "0.0.0.0", port = 64000, }return service_config
运行结果:
阅读全文
0 0
- 网关和客户端交互
- 客户端和服务器数据交互
- tcp服务端和客户端交互
- Android客户端和服务器交互
- UDP服务器和客户端交互
- TCP服务器和客户端交互
- 客户端和服务端交互的东东
- Web客户端和服务器端事件交互问题
- socket服务端和客户端数据通信 数据交互
- Android客户端和Internet的交互
- 《Android攻略》客户端和Service交互
- 手机客户端和服务器的交互步骤
- android客户端和服务端js交互
- zookeeper客户端和服务端交互分析
- android客户端和php服务简单交互
- android客户端和php服务简单交互
- Android客户端和服务器端数据交互
- android客户端和php服务简单交互
- Poj-1961-Period-【KMP】
- 小希的迷宫------幷查集判断是否有环,是否是独立的一棵树
- Ubuntu14.04 CEPH 集群搭建(一)
- Android 获取控件的宽度和高度的几种方式
- Mybatis choose (when, otherwise)标签
- 网关和客户端交互
- C++ 读取ini文件
- handler机制的原理
- docker的基本概念
- python-- 批量整理图片
- 训练赛
- java 动态绑定
- 信息安全——对称算法与非对称算法(转)
- 3D NAND生态全景回顾以及行业展望