制作一个承载想法的东西(八)—— 客户端lua网络模块、服务端skynet

  • A+
所属分类:Unity3d 原创文章

上一篇文章中我在xlua引入了lua-protobuf的库,本来是想在客户端中也把服务端写了的,但是启动后设置reuseaddr出现了权限问题,这也不知道咋解决了,所以决定用一个也是用lua写业务逻辑的服务端skynet来做服务端了。

 

客户端

一、启动的时候引入lua-protobuf

 

二、lua中加载和解析proto

引入lua-protobuff的protoc.lua文件用于加载.proto文件和解析,这个库只是单单的对协议的内容进行解析,前提是你需要知道是哪一个包的message,我称它为cmd。所以需要对数据做一个规定,首先对于协议,我们收到字节流的时候需要知道哪个是头到哪里是尾,所以可以约定前两个字节来表示后面包体的长度,后面四个字节映射一个cmd对应的hash值,最后才跟上proto的解析数据。下面看看这个工具类:

首先是加载proto文件,加载之后会分享和计算出两个列表,用来做cmd和hash的互相映射,方便打包了解包使用。打包的时候,只要传入cmd就可以获取到hashcode用来告知服务端是哪个包,需要前后端使用同一个hash算法。pack打包成"> i2 I4 c%d"的形式,解包的时候先获取前两个字节,解出长度,再接收这个长度的字节流交给unpack处理。

安全进阶:加密和解密、数据校验。通过字码表做映射加密解密,弄一个256长度的加密表和解密表,加密的时候遍历包体的所有字节,字节a转10进制num,该字节就替换为加密表对应索引为num的字节b。同理解密表索引为b的10进制的字节就是a了。数据校验可以将所有的字节10进制相加再加上1,然后取反,字节流头部加多4字节存这个check。拿到数据时就可以将check和所有数据包的字节10进制相加,最后为0就通过验证了。

 

三、基础链接接口

长连接接口,一般有链接、断开链接、发送消息、接收消息、设置链接成功失败断开等回调、还有辅助获取状态的接口等。

 

四、TCP链接

实现基类的方法。发送的时候通过上面写的proto工具,打包协议数据。接收的时候根据规则,获取两字节的包长度,再根据长度获取后面的包体数据,等达到需要的数据时,再解包调用回调去分发消息。随后再接收两字节的包体长度,就这样循环。

这里会出现一个问题,在创建tcp链接的时候,设置了timeout为0,但是在接收数据的时候,解析出了前面2字节的包体长度时,reveive传需要的是整个剩余包体的长度,如果很长,缓存区数据不够会直接返回timeout,后面会卡住一直接收不到数据,也不知道为什么。看了下luasocket的源码,发现应该是当缓存区长度不够时会去等到数据达到需要的长度知道超时,我们超时是0,所以数据不够直接返回timeout了,那只要修改判断一下是timeout的话看看有没有获取到数据,修改错误返回获取到的数据。

 

五、链接管理NetManager

前面都只是实现了一些可以提供调用的方法,其中接收是需要一直去调用的,所以集中在NetManager去管理链接和调用。

 

1.加载proto,注册和分析。

 

2.创建和管理链接

通过几个table存储链接,可以判断正在链接的是否链接成功。已经链接成功的,映射socket和Tcp的实例,方便对方法的调用。

在回调中管理这几个table。

 

3.判断是否连接成功,是否需要接收数据

 

4.事件分发,需要分发的数据类继承这个基类,在构造的时候就会调用注册方法注册进去,需要监听哪个cmd就在CMD_FUNCTION_MAP中用cmd做key,value为方法的字符串或方法。

 

NetManager维护分发列表:

SocketHandlerList管理一个列表:

 

例如:DataBase也是继承SocketReciveData

 

 

5.发送消息

 

六、使用

 

七、暂定,心跳包和断线重连

 

服务端

一、服务端框架编译

  1. 下载skynet1.2.0版本和jemalloc5.1.0版本,将jemalloc放到3rd目录下,整体放到linux服务器上。
  2. cd到skynet目录下,执行make linux编译。
  3. 新建game目录存放项目代码。

 

二、库的引入

  1. 下载lua-protobuf,放到game/lualib-src下,cd到该目录,执行

把pb.so放到game/luaclib

 

2. 下载luafilesystem,放到game/lualib-src下,cd到该目录,执行

把lfs.so放到game/luaclib下

 

三、启动配置

  1. 在game目录下新建config,新建文件config.path和config,添加game下面相关的搜索路径。设置启动服务为startup_node.lua

 

四、创建启动服务和引入lua库

在game目录下新建lualib和service,在lualib中复制一些脚本进去

制作一个承载想法的东西(八)—— 客户端lua网络模块、服务端skynet

 

修改pb_proto.lua,proto协议文件放在game/proto下面

 

在game/service目录下新建startup_node.lua,启动游戏的服务game/maniac.lua

 

五、maniac游戏服务,这里就不详说了,监听数据解析和打包和解包。没有引入数据库和保存数据,同步等等,单纯的转发数据,也没有做分发模块等等,我单纯的想跑通。

 

六、启动和关闭

在skynet目录下,执行

 

远程SSH链接服务器的时候,执行脚本启动斌不是守护进程启动的,但是直接关掉远程链接,服务是不会关掉的,然后不能用ctrl+c去结束了,可以执行:

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: