Moba项目开发(一)打造网络通信系统-任务8:08.创建代理对象实现发送逻辑

文章目录

BufferEntity 通信协议的细节规定
USocket 初始化发送报文的接口
UdpClient 网络报文的处理

1.USocket目的:提供socket发送的接口,以及socket接受的业务

1)修改

public static UClient local; //客户端代理,主要做的是完成发送的逻辑和处理的逻辑,保证报文的顺序

2)初始USocket完善,增加客户端代理

       //提供初始化接口,写个构造函数就可以了
        public USocket(Action<BufferEntity> dispatchNetEvent)
        {
            //参数为0表示系统自动分配
            udpClient = new UdpClient(0);
            server = new IPEndPoint(IPAddress.Parse(ip), port);
            //初始化要调用一下UClient对象,
            //dispatchNetEvent为处理消息分发的行数,传递过去
            UClient local = new UClient(this, server, 0, 0, 0, dispatchNetEvent);
        }

2.客户端代理

1)构造函数初始化
public UClient(USocket uSocket,IPEndPoint endPoint,int sendSN,int handlSN,int sessionID, Action dispatchNetEvent)
2)处理消息(待完善)
没写,待完善
3)发送报文的接口
public void Send(BufferEntity package)
4)超时重传检测接口(待完善)
public async void CheckOutTime()

3.代码

using System.Net;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Threading;

namespace Game.Net
{
    //客户端的代理
    public class UClient
    {
        //参数
        public IPEndPoint endPoint;
        USocket uSocket;                          //USocket内部封装了发送的接口
        public int sessionID;                     //会话ID,客户端只需要接受报文的会话ID赋值就行了
                                                  //服务端要拿到不同的会话ID区分不同的客户端
        public int sendSN = 0;                    //发送序号
        public int handleSN = 0;                  //处理的序号,为了保证报文的顺序性
        //这里为什么要当作形参来传递呢?
        //为了应对以后的业务扩展

        Action<BufferEntity> handleAction;        //定义处理报文的函数,实际就是分发报文给各个游戏模块

        //先来个构造函数->完成初始化
        //sendSN                                  发送的序号
        //handlSN                                 处理的序号
        //sessionID                               会话ID
        //Action<BufferEntity> dispatchNetEvent   派发报文的事件传递进来,也就是待处理的消息
        public UClient(USocket uSocket,IPEndPoint endPoint,int sendSN,int handlSN,int sessionID, Action<BufferEntity> dispatchNetEvent)
        {
            this.uSocket = uSocket;
            this.endPoint = endPoint;
            this.sendSN = sendSN;
            this.handleSN = handleSN;
            this.sessionID = sessionID;
            handleAction = dispatchNetEvent;
        }

        //处理消息

        //定义字典存缓存,int是序号,值是BufferEntity,使用线程安全的字典
        ConcurrentDictionary<int, BufferEntity> sendPackage = new ConcurrentDictionary<int, BufferEntiy>();
        //发送报文的接口
        //这里不需要在void前加async,因为在下面的send已经实现了
        public void Send(BufferEntity package)
        {
            //更新报文发送的时间
            package.time = 0;                        //暂时先等于0
            sendSN += 1;
            package.sn = sendSN;

            package.Encoder(false);                  //对package编码,传递false表示不是ACK的报文
            if (sessionID != 0)                      //等于0表示还没跟服务器建立连接
            {
                //缓存起来,因为可能需要重发(缓存需要定义一个字典)
                sendPackage.TrtAdd(sendSN, package);
            }
            else
            {
                //还没跟服务器建立连接,所以不需要j进行缓存
            }
            uSocket.Send(package.buffer, endPoint);   //客户端的endPoint没啥用,还可以再优化下 


        }

        //定义超时的时间
        int overtime = 150;
        //超时重传检测的接口
        //需要定期从字典里面取出报文,然后判断是否超时就可以了
        public async void CheckOutTime()
        {
            await Tash.Delay(overtime);
            foreach (var package in sendPackage.Values)
            {
                
            }
        }





    }
}

上一篇:Moba项目开发(一)打造网络通信系统-任务11:11.保证报文完整性的处理


下一篇:王者荣耀火起来的原因