Unity3D网络游戏实战——通用客户端模块

本文详细介绍了如何在大乱斗游戏中搭建和优化网络模块,涉及粘包分包处理、心跳机制、事件分发及Json协议的应用,以NetManager为核心,展示了连接、关闭、发送和接收数据的关键代码片段。

前言

书中说的是搭建一套商业级的客户端网络模块,一次搭建长期使用。
本章主要是完善大乱斗游戏中的网络模块,解决粘包分包、完整发送数据、心跳机制、事件分发等功能

6.1网络模块设计

核心是静态类NetManager,它对外提供了一系列方法

  • NetManager.Connect(ip,port)连接服务端
  • NetManager.Close()
  • NetManager.Send(msgMove)发送消息,参数为协议对象,NetManager会自动把它转换成二进制数据
  • NetManager.Update()需外部调用,用于驱动NetManager
  • NetManager.AddMsgListener(“MsgMove”,OnMsgMove)添加消息时间,收到MsgMove协议,就调用OnMsgMove方法
  • NetManager.AddEventListener(NetManager.NetEvent.ConnectSucc,OnConnectSucc),监听网络事件,该语句表示成功调用OnConnetSucc方法

6.1.2内部设计

NetManager基于异步Socket实现,异步socket回调函数把收到的消息按顺序存入消息队列msgList中。Update依次读取信息,根据监听表和协议名,调用相应方法
网络模块分为两个部分。
第一部分:框架模块包含NetManager、ByteArray、MsgBase
第二部分:协议类定义了客户端和服务端通信的数据格式,BattleMsg、SysMsg等

6.1.3code

NetManager的代码,基本都有注释。挑一些重点出来说

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Net.Sockets;
using System;
using System.Linq;

public static class NetManager
{
   
   
    //不用协议名区分监听方法,用NetEvent来区分监听方法
    public enum NetEvent
    {
   
   
        //提供连接成功、失败、断开的回调
        ConnectSucc = 1,
        ConnectFail = 2,
        Close = 3,
    }
    //定义套接字
    static Socket socket;
    //接收缓冲区
    static ByteArray readBuff;
    //写入队列
    static Queue<ByteArray> writeQueue;

    //事件委托类型
    public delegate void EventListener(string err);
    //事件监听列表
    private static Dictionary<NetEvent, EventListener> eventListeners = new Dictionary<NetEvent, EventListener>();

    //消息委托类型,和上面的不一样,上面是用来监听事件的,这里是用来监听消息调用对应的回调函数的
    //和网络事件的添加监听删除监听一样,两者共同组成了NetManager的监听结构
    public delegate void MsgListener(MsgBase msgBase);
    //消息监听列表
    private static Dictionary<string, MsgListener> msgListeners = new Dictionary<string, MsgListener>();

    //消息列表
    static List<MsgBase> msgList = new List<MsgBase>();
    //消息列表长度
    static int msgCount = 0;
    //每一次Update处理的消息量
    readonly static int MAX_MESSAGE_FIRE = 10;

    //是否正在连接
    static bool isConnecting = false;

    //是否正在关闭
    static bool isClosing = false;

    //是否启用心跳
    public static bool isUsePing = true;
    //心跳间隔时间
    public static int pingInterval = 30;
    //上一次发送PING的时间
    static float lastPingTime = 0;
    //上一次收到PONG的时间
    static float lastPongTime = 0;

    //添加事件监听
    public static void AddEventListener(NetEvent netEvent, EventListener listener)
    {
   
   
        //添加事件
        if (eventListeners.ContainsKey(netEvent))
        {
   
   
            //value是委托,可以绑定相同类型的多个函数,后面这个参数就是和该委托类型相同的函数对象
            eventListeners[netEvent] += listener;
        }
        //新增事件
        else
        {
   
   
            eventListeners[netEvent] = listener;
        }
    }

    //删除事件监听
    public static void RemoveEventListener(NetEvent netEvent, EventListener listener)
    {
   
   
        if (eventListeners.ContainsKey(netEvent))
        {
   
   
            eventListeners[netEvent] -= listener;
            //删除
            if (eventListeners[netEvent] == null)
            {
   
   
                eventListeners.Remove(netEvent);
            }
        }
    }

    //分发事件
    private static void FireEvent(NetEvent netEvent, string err)
    {
   
   
        if 
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值