reconnect - woodelf-treetop/rcwiki GitHub Wiki

代码逻辑

​ 网络模块,在lua的应用层,我们可以直接使用 Network.lua,它调用了NetworkManager.cs,NetworkManager调用了SocketClient,SocketClient封装了TcpClient。lua层的使用者只需要关心 Network.lua 的接口。

​ NetworkStream只要是唯一线程写入,另一个线程读取,读取和写入线程之间就不会有交叉干扰,也不需要同步。有两点需要思考:1、luaframework在读取时给加了lock,这样是否会有效率影响;2、在SDK调起时,游戏进入后台,此时我们启动另一个线程给服务器发心跳包,在另一个线程中执行了写入操作,有可能影响线程安全(但最多影响到从SDK切回来的时刻,觉得这个问题还好)

  1. SocketClient.cs

    SocketClient主要接口如下:

        /// 发送连接请求
        public void SendConnect()
    	/// 断开当前tcp
    	public void EndConnect( DisType dis, string msg )
    	///	发送Octets格式的bytes
    	public void SendProtocol( byte[] bytes )

    SocketClient会发送如下消息给外界:

        public class Protocal {
            public const int Connect = 101;     //tcp连接建立
            public const int Exception = 102;     //异常掉线   
            //	本来还有个“正常掉线”,后来发现TcpClient的主动掉线也会通过异常报出,就去掉了
        }

    SocketClient的Close函数是主动关闭tcp连接。tcp连接断开后,通过OnDisconnected告知外界(发送了Protocal.Exception消息),它是唯一出口。

    SocketClient在断开连接时,会触发NetworkManager设置进来的一个回调,把NetworkManager中的协议事件队列sOctetsEvents清空。先清空协议事件队列,再发送Exception消息。

  2. NetworkManager.cs

    NetworkManager依然有发起tcp和断开tcp的接口

        /// 发送链接请求
        public void SendConnect()
    	///	断开
        public void Close()

    它接受SocketClient发来的消息,并在Update中把命令发出去,两类消息都发送给了Network.lua

    --Socket消息--	(tcp的连接和断开)
    function Network.OnSocket(key, data)
        --	实际关联到如下两处	--
        function Network.OnConnect()
        function Network.OnException()
    --Protocol协议--
    function Network.OnProtocolMessage(key, os, inBackground )
  3. Network.lua

    tcp断开

    ​ tcp断开连接,存在三种情况:合法断开、建立连接不成功、连接中意外断开(主动断开也可导致)

    Network.OnException 是lua层收到网络断开消息的唯一入口,isOnNetwork属性可以判断是否已经在连接中,如果在tcp连接中,Network会把这事儿交给RunningLuaManager处理。因为RunningLuaManager才知道这时候的全部信息,比如是否在游戏重启过程中,从而决定这个时候断网了该做些什么。

    ​ Network为RunningLuaManager提供了一个接口 CheckLegality,如果是主动断开,会认为是合法断开,就不会发起重连。

    tcp连接成功

    Network.OnConnect 是lua层收到网络连接成功消息的唯一入口

    发起tcp连接

    ​ Network.StartConnect

    主动断开tcp连接

    ​ Network.StopConnect

    检测(在从后台切到前台的时候进行)

    ​ Network.CheckNet

    重要状态

    • ​ isOnNetwork

      ​ 是否在连接中。它在 Network.OnConnect 中被置为true,在 Network.OnException 被置为false。只有这两处修改它的值

    • ​ isConnecting

      是否正在连接的过程中,当连接上,或者连接失败,它都会为false

  4. ConnectCtrl.lua

    ​ 主要功能:界面操作挡板、断线重连。

    ​ 往服务器发消息时,会激活挡板禁止用户操作,直到服务器反馈,取消挡板;如果服务器不反馈,此时主动断开tcp连接;如果tcp断开,启动断线重连。

    ConnectCtrl.ConnectUpdate 是一个常驻的Update,负责挡板计时与断开tcp

    ConnectCtrl.Update 负责断线重连功能,只在断线重连期间激活,它通过如下状态展现

    local CONNECT_STATUS = {
        FIRST_TEST = "firstTest",       --  重连尝试阶段,此时只屏蔽操作,不显示倒计时,如果这个时间内连上了,就直接取消挡板
        PROCESS = "process",            --  显示了倒计时,15秒重连不上就弹对话框让用户选择重启或再次重连;3个15秒之后,用户只能重启
        WAITING = "waiting",            --  弹出了对话框,等待玩家点确定
        CONNECTED = "connected",        --  已连接成功,需要等待1秒,此时界面上显示“连接成功”字样
        NONE = "none",                  --  初始状态
    }

    ​ 外界启动断线重连的入口,是 ConnectCtrl.StartReConnect,从这里激活了ConnectCtrl.Update。

  5. 断线重连Q&A

    ​ 暂无

⚠️ **GitHub.com Fallback** ⚠️