GateServer的使用

skynet 提供了一个通用模板 lualib/snax/gateserver.lua 来启动一个网关服务器,通过 TCP 连接和客户端交换数据。

TCP 基于数据流,但一般我们需要以带长度信息的数据包的结构来做数据交换。gateserver 做的就是这个工作,把数据流切割成包的形式转发到可以处理它的地址。
skynet 提供了一个 lua 库 netpack ,用来把 tcp 流中的数据解析成 长度 + 内容的包。
gateserver就是使用netpack进行包解析。

在同一个目录建立7个文件(config,proto.lua,main.lua,mygate.lua,socket1.lua,service1.lua,client1.lua)

本例子的client1使用前两节的client,代码稍作修改。

client1.lua代码:

package.cpath = "luaclib/?.so"
package.path = "lualib/?.lua;myexample/e5/?.lua"if _VERSION ~= "Lua 5.3" thenerror "Use lua 5.3"
endlocal socket = require "clientsocket"-- 通信协议
local proto = require "proto"
local sproto = require "sproto"local host = sproto.new(proto.s2c):host "package"
local request = host:attach(sproto.new(proto.c2s))local fd = assert(socket.connect("127.0.0.1", 8888))local session = 0-- 封包(长度+内容)
local function send_package(fd, pack)local package = string.pack(">s2", pack)socket.send(fd, package)
endlocal function send_request(name, args)session = session + 1local str = request(name, args, session)-- socket.send(fd, str)-- 添加数据长度包头,gateserver接收自动判断类型为data(gateserver使用了netpack进行解析)-- skynet 提供了一个 lua 库 netpack ,用来把 tcp 流中的数据解析成 长度 + 内容的包。send_package(fd,str);print("Request:", session)
endsend_request("handshake")
send_request("say", { name = "soul", msg = "hello world" })while true do-- 接收服务器返回消息local str   = socket.recv(fd)-- print(str)if str~=nil and str~="" thenprint("server says: "..str)-- socket.close(fd)-- break;end-- 读取用户输入消息local readstr = socket.readstdin()if readstr thenif readstr == "quit" thensend_request("quit")-- socket.close(fd)-- break;else-- 把用户输入消息发送给服务器send_request("say", { name = "soul", msg = readstr })endelsesocket.usleep(100)endend

socket1.lua代码:

local skynet = require "skynet"
local common = require "common"local gateskynet.start(function()print("==========Socket Start=========")print("Listen socket :", "127.0.0.1", 8888)-- Socket服务配置local conf = {address = "127.0.0.1",port = 8888,maxclient = 1024,nodelay = true,}-- common:dump(conf)-- 启动Socket管理网关gate=skynet.newservice("mygate")-- 打开监听端口skynet.call(gate, "lua", "open" , conf)end)

mygate.lua代码:

local skynet = require "skynet"
local gateserver = require "snax.gateserver"
local netpack = require "netpack"
local common = require "common"local connection = {}    -- fd -> connection : { fd , ip }
local handler = {}local agentlist = {}-- 当一个完整的包被切分好后,message 方法被调用。这里 msg 是一个 C 指针、sz 是一个数字,表示包的长度(C 指针指向的内存块的长度)。
function handler.message(fd, msg, sz)print("===========gate handler.message============"..fd)-- common:dump(connection[fd])local c = connection[fd]local agent = agentlist[fd]if agent then-- skynet.redirect(agent, c.client, "client", 1, msg, sz)print("接收到客户端消息,传给agent服务处理")elseprint("没有agent处理该消息")end
endfunction handler.connect(fd, addr)print("===========gate handler.connect============")local c = {fd = fd,ip = addr,}-- common:dump(c)-- 保存客户端信息connection[fd] = c-- 马上允许fd 接收消息(由于下面交给service1处理消息,所以可以在service1准备好再调用)-- 这样可能导致客户端发来的消息丢失,因为service1未准备好的情况下,无法处理消息gateserver.openclient(fd)agentlist[fd] = skynet.newservice("service1")skynet.call(agentlist[fd], "lua", "start", { fd = fd, addr = addr })
endfunction handler.disconnect(fd)print(fd.."-断开连接")
endfunction handler.error(fd, msg)print("异常错误")
endgateserver.start(handler)

service1.lua代码:

local common = require "common"
local skynet = require "skynet"
require "skynet.manager"  -- import skynet.registerlocal CMD = {}
local client_fd
local host-- TODO
-- skynet.register_protocol
-- 注册新的消息类别 PTYPE_CLIENT,新的类别必须提供 pack 和 unpack 函数,用于消息的编码和解码。function CMD.start(conf)print("service1 CMD.start")-- common:dump(conf)-- SOCKET处理
endfunction CMD.disconnect()-- todo: do something before exitskynet.exit()
endskynet.start(function()print("==========Service1 Start=========")skynet.dispatch("lua", function(session, address, cmd, ...)print("==========Service1 dispatch============"..cmd)local f = CMD[cmd]skynet.ret(skynet.pack(f(...)))end)
end)

项目源码:http://download.csdn.net/detail/uisoul/9806650
API参考文档:https://github.com/cloudwu/skynet/wiki/GateServer

Skynet基础入门例子详解(7)相关推荐

  1. Skynet基础入门例子详解(1)

    Skynet 是一个轻量级的为在线游戏服务器打造的框架,它也不仅仅使用在游戏服务器领域. Skynet开源项目地址: https://github.com/cloudwu/skynet 云风大神博客: ...

  2. JavaScript基础入门-----万字详解

    浏览器执行JS简介 浏览器分成两大部分 渲染引擎和JS 引擎 渲染引擎: 用来解析HTML与CSS,俗称内核,比如chrome浏览器的blink,老版本的webkit JS 引擎:也称为JS 解释器. ...

  3. STM32基础入门——GPIO详解

    目录 一.GPIO的简介 二.GPIO工作模式-----输入 1.浮空输入模式 2.上拉输入模式 3.下拉输入模式 4.模拟输入模式 三.GPIO工作模式-----输出 1.开漏输出模式 2.推挽输出 ...

  4. [Python从零到壹] 五.网络爬虫之BeautifulSoup基础语法万字详解

    欢迎大家来到"Python从零到壹",在这里我将分享约200篇Python系列文章,带大家一起去学习和玩耍,看看Python这个有趣的世界.所有文章都将结合案例.代码和作者的经验讲 ...

  5. python 快速排序_小白入门知识详解:Python实现快速排序的方法(含实例代码)...

    前言: 今天为大家带来的内容是:小白入门知识详解:Python实现快速排序的方法(含实例代码)希望通过本文的内容能够对各位有所帮助,喜欢的话记得点赞转发收藏不迷路哦!!! 提示: 这篇文章主要介绍了P ...

  6. [系统安全] 四十四.APT系列(9)Metasploit技术之基础用法万字详解及防御机理

    您可能之前看到过我写的类似文章,为什么还要重复撰写呢?只是想更好地帮助初学者了解病毒逆向分析和系统安全,更加成体系且不破坏之前的系列.因此,我重新开设了这个专栏,准备系统整理和深入学习系统安全.逆向分 ...

  7. [Python从零到壹] 九.网络爬虫之Selenium基础技术万字详解(定位元素、常用方法、键盘鼠标操作)

    欢迎大家来到"Python从零到壹",在这里我将分享约200篇Python系列文章,带大家一起去学习和玩耍,看看Python这个有趣的世界.所有文章都将结合案例.代码和作者的经验讲 ...

  8. python 3.x 爬虫基础---http headers详解

    python 3.x 爬虫基础 python 3.x 爬虫基础---http headers详解 python 3.x 爬虫基础---Urllib详解 python 3.x 爬虫基础---Requer ...

  9. python average函数详解_python基础之函数详解

    Python基础之函数详解 一.函数的定义 到现在为止,我们已经掌握了Python的基本语法和数据类型等相关基础知识了,以进行一个项目的编写了,这个时候,就会发现,很多代码需要我们进行复制粘贴,这简直 ...

最新文章

  1. web前端开发培训完就业前景怎么样
  2. python类中方法的执行顺序-Python中实例化class的执行顺序示例详解
  3. 在envi做随机森林_随机森林原理
  4. jquery mobile资源
  5. 如何在网页读取用户IP,操作系统版本等数据demo
  6. HTTP协议扫盲(一)HTTP协议的基本概念和通讯原理
  7. http 二进制_百度云加速科普小课堂-HTTP/2解析
  8. 微软提高 Microsoft 365 的漏洞奖励
  9. 先河系统为你讲解私有云服务器的优点
  10. SecureCRT使用技巧连载
  11. 如何点击单选框 radio 后面的文字,选中单选框
  12. P1879 [USACO06NOV]玉米田Corn Fields
  13. 29个用于石油和天然气等行业的最佳 GIS 软件
  14. 换IP软件如何使用,一起来看下换IP软件的使用教程
  15. 《机器学习实战笔记--第一部分 分类算法:决策树 3》
  16. python 实现文字识别提取
  17. 《费马大定理》-站在巨人的肩膀上
  18. 求多个数的最小公倍数或最大公约数
  19. 【SpringBoot注解-4】:@Target、@Retention、@Documented注解简介
  20. HEVC(H.265) 基础知识

热门文章

  1. 小二,来碗另类quot;反鸡汤quot;
  2. 微信一键群发怎么超过200好友?
  3. 利用向量计算角平分线并判断点相对于角平分线的位置(JAVA版)
  4. uboot网卡驱动移植
  5. Firefox 将启用全新 logo 设计,不同图标对应不同产品线
  6. Python -- Effective Python:编写高质量Python代码的59个有效方法
  7. 对于顺序表和链表的区别
  8. 2353409-99-9,DBCO-PEG9-amine,DBCO-PEG9-NH2,二苯并环辛炔-九聚乙二醇-氨基供应
  9. weblogic不能启动的解决方案;发现启动过程中AdminServer.lok文件报错,导致weblogic不能启动
  10. 体验Mac OS Monterey前,应做好这5件事