• 自己设计的一套实用的针对中小型网络游戏的网络通信框架

    大家好,我是FoldCc,今天给大家分享一下自己设计并且经常用到的一个网络通信框架---客户端

    经过自己的实践,发现这套框架在应对一些中小型手游还是比较稳定使用的,整体结构也比较简单,但是特别实用,唯一要注意一点的是在开发网络通信时,一定要注意多线程争用资源的问题。

    下面我为大家详细介绍一下:

    首先最核心的是Socket连接器 它的功能主要有4个

    》向服务器发起连接请求

    》一个能够返回已经连接服务器的Socket的方法(仅用于之后开启接收和发送消息线程)

    》判断当前是否连接正常

    》断开服务器连接

    当连接器连接成功后会自动创建两个线程,分别用来接收和发送,(至于为什么要单独分开成两个,是因为在实际应用中一个线程处理这两个效率上低,容易出问题,并且理论上来说一个线程同时处理发送和接收也有点不合理)为了防止接收和发送线程在处理消息可能出现效率跟不上的问题,我设置了两个消息队列,分别用来装发送的消息和接收的消息,其中接收的消息通过消息分类器分类到不同队列中,这里需要注意的一点是,接收消息需要做粘包处理!说通俗一点就是判断消息的完整性,这里我为所有消息都加了一个特定的消息头 和消息尾 用来判断消息的完整性,至于消息头和消息尾的内容由自己设计,最好是不常使用的一些特殊字符,防止遇到和内容相同的情况。

    两个线程则只负责将收到的消息往队列中存储以及将发送队列的消息按顺序发送就行了,消息分类会单独去对消息进行分类并存放到对应队列中。

    下面是这一套框架的流程图,如果有用大家帮忙转载哦!大笑

    展开全文
  • 前言:  protobuf是google的一个开源项目,...2.制作网络通信协议; 一、资源下载: 1.github源码地址:https://github.com/mgravell/protobuf-net 2.google项目源码下载地址(访问需翻墙):https://code.google

    前言:

            protobuf是google的一个开源项目,主要的用途是:

    1.数据存储(序列化和反序列化),这个功能类似xml和json等;

    2.制作网络通信协议;


    一、资源下载:

    1.github源码地址:https://github.com/mgravell/protobuf-net

    2.google项目源码下载地址(访问需翻墙):https://code.google.com/p/protobuf-net/


    二、数据存储:

            C#语言方式的导表和解析过程,在之前的篇章中已经有详细的阐述:Unity —— protobuf 导excel表格数据,建议在看后续的操作之前先看一下这篇文档,因为后面设计到得一些操作与导表中是一致的,而且在理解了导表过程之后,能够快速地理解协议数据序列化反序列化的过程。


    三、网络协议:

    1.设计思想:

            有两个必要的数据:协议号协议类型,将这两个数据分别存储起来

    • 当客户端向服务器发送数据时,会根据协议类型加上协议号,然后使用protobuf序列化之后再发送给服务器;
    • 当服务器发送数据给客户端时,根据协议号,用protobuf根据协议类型反序列化数据,并调用相应回调方法。

            由于数据在传输过程中,都是以数据流的形式存在的,而进行解析时无法单从protobuf数据中得知使用哪个解析类进行数据反序列化,这就要求我们在传输protobuf数据的同时,携带一个协议号,通过协议号和协议类型(解析类)之间的对应关系来确定进行数据反序列化的解析类。

           

            此处协议号的作用就是用来确定用于解析数据的解析类,所以也可能称之为协议类型名,可以是stringint类型的数据。


    2.特点分析:

           使用protobuf作为网络通信的数据载体,具有几个优点:

    • 通过序列化之后数据量比较小
    • 而且以key-value的方式存储数据,这对于消息的版本兼容比较强;
    • 此外,由于protobuf提供的多语言支持,所以使用protobuf作为数据载体定制的网络协议具有很强的跨语言特性

    四、样例实现:

    1.协议定义:

            在之前导表的时候,我们得到了.proto的解析类,这是protobuf提供的一种特殊的脚本,具有格式简单、可读性强和方便拓展的特点,所以接下来我们就是使用proto脚本来定义我们的协议。例如:

    // 物品
    message Item
    {
        required int32 Type 	= 1;	//游戏物品大类
        optional int32 SubType 	= 2;	//游戏物品小类
        required int32 num 		= 3;	//游戏物品数量
    }
    
    // 物品列表
    message ItemList
    {
        repeated Item item 	= 1;	//物品列表
    }
            上述例子中,Item相当于定义了一个数据结构或者是类,而ItemList是一个列表,列表中的每个元素都是一个Item对象。注意结构关键词:

    • required:必有的属性
    • optional:可选属性
    • repeated:数组
            其实protobuf在这里只是提供了一个数据载体,通过在.proto中定义数据结构之后,需要使用与导表时一样的操作,步骤为:

    • 使用protoc.exe将.proto文件转化为.protodesc中间格式;
    • 使用protogen.exe将中间格式为.protodesc生成指定的高级语言类,我们在Unity中使用的是C#,所以结果是.cs类
            经过上述步骤之后,我们得到了协议类型对应的C#反序列化类,当我们收到服务器数据时,根据协议号找到协议类型,从而使用对应的反序列化的类对数据进行反序列化,得到最终的服务器数据内容。

            在这里,我们以登录为例,首先要清楚登录需要几个数据,正常情况下至少包含两个数据,即账号和密码,都是字符串类型,即定义cs_login.proto协议脚本,内容如下:
    package cs;
    
    message CSLoginInfo
    {
    	required string UserName = 1;//账号
    	required string Password = 2;//密码
    }
    
    //发送登录请求
    message CSLoginReq
    {
    	required CSLoginInfo LoginInfo = 1; 
    }
    //登录请求回包数据
    message CSLoginRes
    {
    	required uint32 result_code = 1; 
    }
           package关键字后面的名称为.proto转为.cs之后的命名空间namespace的值,用message可以定义类,这里定义了一个CSLoginInfo的数据类,该类包含了账号和密码两个字符串类型的属性。然后定义了两个消息结构:
    • CSLoginReq登录请求消息,携带的数据是一个CSLoginInfo类型的对象数据;
    • CSLoginRes登录请求服务器返回的数据类型,返回结果是一个uint32无符号的整型数据,即结果码。
            上面定义的是协议类型,除此之外我们还需要为每一个协议类型定义一个协议号,这里可以用一个枚举脚本cs_enum.proto来保存,脚本内容为:
    package cs;
    
    enum EnmCmdID
    {
    	CS_LOGIN_REQ = 10001;//登录请求协议号
    	CS_LOGIN_RES = 10002;//登录请求回包协议号
    }
    
            使用protoc.exe和protogen.exe将这两个protobuf脚本得到C#类,具体步骤参考导表使用的操作,这里我直接给出自动化导表使用的批处理文件general_all.bat内容,具体文件目录可以根据自己放置情况进行调整:
    ::---------------------------------------------------
    ::第二步:把proto翻译成protodesc
    ::---------------------------------------------------
    call proto2cs\protoc protos\cs_login.proto --descriptor_set_out=cs_login.protodesc
    call proto2cs\protoc protos\cs_enum.proto --descriptor_set_out=cs_enum.protodesc
    ::---------------------------------------------------
    ::第二步:把protodesc翻译成cs
    ::---------------------------------------------------
    call proto2cs\ProtoGen\protogen -i:cs_login.protodesc -o:cs_login.cs
    call proto2cs\ProtoGen\protogen -i:cs_enum.protodesc -o:cs_enum.cs
    ::---------------------------------------------------
    ::第二步:把protodesc文件删除
    ::---------------------------------------------------
    del *.protodesc
    
    pause
            转换结束后,我们的得到了两个.cs文件分别是:cs_enum.cs和cs_login.cs,将其放入到我们的Unity项目中,以便于接下来序列化和反序列化数据的使用。


    2.协议数据构建:

            直接在项目代码中通过usingcs引入协议解析类的命名空间,然后创建消息对象,并对对象的属性进行赋值,即可得到协议数据对象,例如登录请求对象的创建如下:

            CSLoginInfo mLoginInfo = new CSLoginInfo();
            mLoginInfo.UserName = "linshuhe";
            mLoginInfo.Password = "123456";
            CSLoginReq mReq = new CSLoginReq();
            mReq.LoginInfo = mLoginInfo;
            从上述代码,可以得到登录请求对象mReq,里面包含了一个CSLoginInfo对象mLoginInfo,再次枚举对象中找到与此协议类型对应的协议号,即:EnmCmdID.CS_LOGIN_REQ


    3.数据的序列化和反序列化:

            数据发送的时候必须以数据流的形式进行,所以这里我们需要考虑如何将要发送的protobuf对象数据进行序列化,转化为byte[]字节数组,这就需要借助ProtoBuf库为我们提供的Serializer类的Serialize方法来完成,而反序列化则需借助Deserialize方法,将这两个方法封装到PackCodec类中:

    using UnityEngine;
    using System.Collections;
    using System.IO;
    using System;
    using ProtoBuf;
    
    /// <summary>
    /// 网络协议数据打包和解包类
    /// </summary>
    public class PackCodec{
        /// <summary>
        /// 序列化
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="msg"></param>
        /// <returns></returns>
        static public byte[] Serialize<T>(T msg)
        {
            byte[] result = null;
            if (msg != null)
            {
                using (var stream = new MemoryStream())
                {
                    Serializer.Serialize<T>(stream, msg);
                    result = stream.ToArray();
                }
            }
            return result;
        }
    
        /// <summary>
        /// 反序列化
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="message"></param>
        /// <returns></returns>
        static public T Deserialize<T>(byte[] message)
        {
            T result = default(T);
            if (message != null)
            {
                using (var stream = new MemoryStream(message))
                {
                    result = Serializer.Deserialize<T>(stream);
                }
            }
            return result;
        }
    }
            使用方法很简单,直接传入一个数据对象即可得到字节数组:

            byte[] buf = PackCodec.Serialize(mReq);

            为了检验打包和解包是否匹配,我们可以直接做一次本地测试:将打包后的数据直接解包,看看数据是否与原来的一致:

    using UnityEngine;
    using System.Collections;
    using System;
    using cs;
    using ProtoBuf;
    using System.IO;
    
    public class TestProtoNet : MonoBehaviour {
    
    	// Use this for initialization
    	void Start () {
            CSLoginInfo mLoginInfo = new CSLoginInfo();
            mLoginInfo.UserName = "linshuhe";
            mLoginInfo.Password = "123456";
            CSLoginReq mReq = new CSLoginReq();
            mReq.LoginInfo = mLoginInfo;
    
            byte[] pbdata = PackCodec.Serialize(mReq);
            CSLoginReq pReq = PackCodec.Deserialize<CSLoginReq>(pbdata);
            Debug.Log("UserName = " + pReq.LoginInfo.UserName + ", Password = " + pReq.LoginInfo.Password);
    	}
    
        // Update is called once per frame
        void Update () {
    	
    	}
    }

            将此脚本绑到场景中的相机上,运行得到以下结果,则说明打包和解包完全匹配:
            


    4.数据发送和接收:

            这里我们使用的网络通信方式是Socket的强联网方式,关于如何在Unity中使用Socket进行通信,可以参考我之前的文章:Unity —— Socket通信(C#),Unity客户端需要复制此项目的ClientSocket.csByteBuffer.cs两个类到当前项目中。

            此外,服务器可以参照之前的方式搭建,唯一不同的是RecieveMessage(object clientSocket)方法解析数据的过程需要进行修改,因为需要使用protobuf-net.dll进行数据解包,所以需要参考客户端的做法,把protobuf-net.dll复制到服务器项目中的Protobuf_net目录下:

            
            假如由于直接使用源码而不用.dll会出现不安全保存,需要在Visual Studio中设置允许不安全代码,具体步骤为:在“解决方案”中选中工程,右键“数据”,选择“生成”页签,勾选“允许不安全代码”:

             

              当然,解析数据所用的解析类和协议号两个脚本cs_login.cs和cs_enum.cs也应该添加到服务器项目中,保证客户端和服务器一直,此外PackCodec.cs也需要添加到服务器代码中但是要把其中的using UnityEngine给去掉防止报错,最终服务器目录结构如下:

             


    5.完整协议数据的封装:

            从之前说过的设计思路分析,我们在发送数据的时候除了要发送关键的protobuf数据之外,还需要带上两个附件的数据:协议头(用于进行通信检验)和协议号(用于确定解析类)。假设我们的是:

           协议头:用于表示后面数据的长度一个short类型的数据:

            /// <summary>
            /// 数据转换,网络发送需要两部分数据,一是数据长度,二是主体数据
            /// </summary>
            /// <param name="message"></param>
            /// <returns></returns>
            private static byte[] WriteMessage(byte[] message)
            {
                MemoryStream ms = null;
                using (ms = new MemoryStream())
                {
                    ms.Position = 0;
                    BinaryWriter writer = new BinaryWriter(ms);
                    ushort msglen = (ushort)message.Length;
                    writer.Write(msglen);
                    writer.Write(message);
                    writer.Flush();
                    return ms.ToArray();
                }
            }

           协议号:用于对应解析类,这里我们使用的是int类型的数据:

            private byte[] CreateData(int typeId,IExtensible pbuf)
        {
            byte[] pbdata = PackCodec.Serialize(pbuf);
            ByteBuffer buff = new ByteBuffer();
            buff.WriteInt(typeId);
            buff.WriteBytes(pbdata);
            return buff.ToBytes();
        }
            客户端发送登录数据时测试脚本TestProtoNet如下,测试需要将此脚本绑定到当前场景的相机上:

    using UnityEngine;
    using System.Collections;
    using System;
    using cs;
    using Net;
    using ProtoBuf;
    using System.IO;
    
    public class TestProtoNet : MonoBehaviour {
    
    	// Use this for initialization
    	void Start () {
    
    
            CSLoginInfo mLoginInfo = new CSLoginInfo();
            mLoginInfo.UserName = "linshuhe";
            mLoginInfo.Password = "123456";
            CSLoginReq mReq = new CSLoginReq();
            mReq.LoginInfo = mLoginInfo;
    
            byte[] data = CreateData((int)EnmCmdID.CS_LOGIN_REQ, mReq);
            ClientSocket mSocket = new ClientSocket();
            mSocket.ConnectServer("127.0.0.1", 8088);
            mSocket.SendMessage(data);
        }
    
        private byte[] CreateData(int typeId,IExtensible pbuf)
        {
            byte[] pbdata = PackCodec.Serialize(pbuf);
            ByteBuffer buff = new ByteBuffer();
            buff.WriteInt(typeId);
            buff.WriteBytes(pbdata);
            return WriteMessage(buff.ToBytes());
        }
    
        /// <summary>
        /// 数据转换,网络发送需要两部分数据,一是数据长度,二是主体数据
        /// </summary>
        /// <param name="message"></param>
        /// <returns></returns>
        private static byte[] WriteMessage(byte[] message)
        {
            MemoryStream ms = null;
            using (ms = new MemoryStream())
            {
                ms.Position = 0;
                BinaryWriter writer = new BinaryWriter(ms);
                ushort msglen = (ushort)message.Length;
                writer.Write(msglen);
                writer.Write(message);
                writer.Flush();
                return ms.ToArray();
            }
        }
    
        // Update is called once per frame
        void Update () {
    	
    	}
    }
            服务器接受数据解包过程参考打包数据的格式,在RecieveMessage(object clientSocket)中,解析数据的核心代码如下:

            ByteBuffer buff = new ByteBuffer(result);
            int datalength = buff.ReadShort();
            int typeId = buff.ReadInt();
            byte[] pbdata = buff.ReadBytes();
            //通过协议号判断选择的解析类
            if(typeId == (int)EnmCmdID.CS_LOGIN_REQ)
            {
                    CSLoginReq clientReq = PackCodec.Deserialize<CSLoginReq>(pbdata);
                    string user_name = clientReq.LoginInfo.UserName;
                    string pass_word = clientReq.LoginInfo.Password;
                    Console.WriteLine("数据内容:UserName={0},Password={1}", user_name, pass_word);
                    }
            }
            上面通过typeId来找到匹配的数据解析类,协议少的时候可以使用这种简单的使用if语句分支判断来实现,但是假如协议类型多了,则需要进一步封装查找方法,常用的方法有:定义一个Dictionary<int,Type>字典来存放协议号(int)和协议类型(Type)的对应关系。


    6.运行结果:

            启动服务器,然后运行Unity中的客户端,得到正确的结果应该如下:

            

            项目服务器和客户端的完整代码可以前往此处下载:protobuf-net网络协议的定制


    展开全文
  • 本文视频链接地址:... *************************************笔记总结************************************** 1.tcp/udp传输协议、ip网络协议 2、Socket相当于tcp、udp协议的封装 3、socke...

    相关网盘免费资源下载...

     

    本文视频链接地址:http://m.maiziedu.com/course/654-10935/

     

    *************************************笔记总结**************************************

    1.tcp/udp传输协议、ip网络协议

     

     

    2、Socket相当于tcp、udp协议的封装

    3、socket简单应用

    5、protobuf(数据接收格式)介绍

    6、WWWForm是一种post请求方式(unity)

    7、如果创建创建小型的的BS多人同步服务器,可以使用netWorkView(轻量级)

    8、Photon引擎简介

    9、开放端口(不受window防火墙屏蔽),有两种方式:

    ①手动添加整个程序,使得整个程序在启动、执行时,(所使用的端口)成为白名单

    ②手动开放指定端口

    10、byte类型取值0-255

    11、Unity单例模式:

     

    相关网盘免费资源下载...

    展开全文
  • Unity3D 网络通信_HTTP协议、处理Json格式返回值、请求加Oauth

    Unity3D 网络通信_HTTP协议、处理Json格式返回值、请求加Oauth

    post


    get


    登录

    using UnityEngine;
    using System.Collections;
    using System.Collections.Generic;
    using System.Text;
    using System.Security.Cryptography;
    using System.Security.Authentication;
    using LitJson;
    using System;
    using System.Globalization; 
    using System.Security.Cryptography;
    using System.Web;
    
    public static string url = "http://localhost:8080/film/";
    
    public void Login(string username , string password)
    	{	
    		string path = "/film/api/tqh/v2/member/login";
    		StartCoroutine(PostLogin(url+"api/tqh/v2/member/login?",path,username,password));		
    	}
    IEnumerator PostLogin(string url,string path,string username , string password)
    	{
    		string input = "{\"email\":\""+username+"\",\"password\":\""+	ToMd5(password)+"\"}";
    		WWWForm form = new WWWForm();		
    		Hashtable headers = form.headers;
    		byte[] rawData = Encoding.UTF8.GetBytes(input);
    		headers["Content-Type"] = "application/json";
    		headers["Accept"] = "application/json";
    
    		DateTime date = DateTime.Now;
    		string time =  date.ToString("ddd, yyyy-mm-dd HH':'mm':'ss 'UTC'",DateTimeFormatInfo.InvariantInfo);
    		headers["Date"] = time;
    		url = hmac(url,path,time);
    
    		WWW www = new WWW(url, rawData, headers);
    		yield return www;		
    		if (www.error != null)
    		{
    			Debug.Log("error is login:"+ www.error  + "  " +input );	
    			camara.GetComponent<loginGUI>().loginfail(status_fail);
    		} else
    		{
    			Debug.Log("request ok login: " + www.text);
    
    			JsonData jd = JsonMapper.ToObject(www.text); 
    
    			string memberId = jd["memberId"].ToString();
    			string bonusPoint = jd["bonusPoint"].ToString();
    			string nickName = jd["nickName"].ToString();
    			camara.GetComponent<loginGUI>().loginsuccess(memberId,nickName,bonusPoint,status_success);
    		}
    	}

    oauth使用在headers中加入Date,date.ToString("ddd, yyyy-mm-dd HH':'mm':'ss 'UTC'",DateTimeFormatInfo.InvariantInfo)对日期的格式化

    string time =  date.ToString("ddd, yyyy-mm-dd HH':'mm':'ss 'UTC'",DateTimeFormatInfo.InvariantInfo);

    headers["Date"] = time;

    www.text为后台返回的String字符串,是Json格式,但是不可以直接用key-value去取值,我们需要去转换使用LitJson,一个第三方插件


    
    
    
    

    JsonData jd = JsonMapper.ToObject(www.text); 

    string memberId = jd["memberId"].ToString();
    string bonusPoint = jd["bonusPoint"].ToString();
    string nickName = jd["nickName"].ToString();

    在unity\项目\Assets\Plugins目录下引用LitJson,下载LitJson


    之后就可以用key-value去取值了   

    oauth的加入

    public static  string API_KEY = "bc543dc89b***********";
    public  static string SECURE_KEY = "32df2bc3520d53a1************";

    	public string hmac(string url ,string path ,string time){
    		StringBuilder stringToSign = new StringBuilder();
    		stringToSign.Append("POST").Append("\n");
    		stringToSign.Append(time).Append("\n");
    		stringToSign.Append(path).Append("\n");	
    
    		var signature = string.Empty;
    		using (var hmac = new HMACSHA512(Encoding.UTF8.GetBytes(SECURE_KEY)))
    		{
    			var hash = hmac.ComputeHash(Encoding.UTF8.GetBytes(stringToSign.ToString()));
    			signature = Convert.ToBase64String(hash);
    		}
    
    		StringBuilder s = new StringBuilder();
    		s.Append(url);
    		s.Append("&apiKey=");
    		s.Append(HttpUtility.UrlEncode(API_KEY, Encoding.UTF8));
    		s.Append("&signature=");
    		s.Append(HttpUtility.UrlEncode(HttpUtility.UrlEncode(signature, Encoding.UTF8), Encoding.UTF8));
    
    		return s.ToString();
    	}


    StringBuilder stringToSign = new StringBuilder();
    stringToSign.Append("POST").Append("\n");
    stringToSign.Append(time).Append("\n");
    stringToSign.Append(path).Append("\n");

    
    

    需要通过 httpMethod、time、和path(格式为"/film/api/tqh/v2/public/getAllHistoryRank")来获取HMACSHA512加密后的签名

    var hmac = new HMACSHA512(Encoding.UTF8.GetBytes(SECURE_KEY))

    对API_KEY和签名进行编码,签名编码两次是因为,在服务器被解码了两次一次jetty、一次后台

    StringBuilder s = new StringBuilder();s.Append(url);s.Append("&apiKey=");s.Append(HttpUtility.UrlEncode(API_KEY, Encoding.UTF8));s.Append("&signature=");s.Append(HttpUtility.UrlEncode(HttpUtility.UrlEncode(signature, Encoding.UTF8), Encoding.UTF8));

    HttpUtility使用需要引入的 using System.Web; 下载HttpUtility

    
    
    
    

    展开全文
  • 不同模块之间的消息通信机制,简单易懂,主要包括消息体以及消息中心,注册和发送消息
  • Unity3d实战之Unity3d网络游戏实战篇(6):服务端框架的搭建 学习书籍《Unity3d网络游戏实战》 罗培羽著 机械工业出版社 本文是作者在学习过程中遇到的认为值得记录的点,因此引用的代码等资源基本出资罗培羽...

    Unity3d实战之Unity3d网络游戏实战篇(6):服务端框架的搭建

    学习书籍《Unity3d网络游戏实战》 罗培羽著 机械工业出版社
    本文是作者在学习过程中遇到的认为值得记录的点,因此引用的代码等资源基本出资罗培羽老师的书籍
    以下为个人的学习简记,与诸君共论 由于U3D的官方案例Tank Tutorial中对坦克的基本操作已经有了详尽的描述,因此本文着重于面板系统、服务端基本网络框架和客户端基本网络框架的搭建
    如有疑问或者描述错误的地方,欢迎各位提出或修正,讨论交流是获取和巩固知识的重要途径之一!

     整个服务端框架分为3层:
    这里写图片描述
     底层:负责Client的监听、数据处理、协议构建、数据库操作等。
     中间层:对客观世界事物的抽象,实现类对象的各种方法;
     逻辑层:实现游戏逻辑,根据接收到的不同协议实现不同的逻辑。

     服务端框架的目录结构如下:
     这里写图片描述
     底层:
      ServNet:处理Server与各Client的连接以及数据接收;
      DataMgr:根据需求实现对数据库的各种操作;
      Protocol:编写协议实现Server与Client之间的有效通信;
     中间层:
      Player:对玩家的抽象,拥有玩家id、角色、下线等方法的实现;
      Conn:实现Server与Client之间的连接的管理,其作用与第四节描述的一致;
     逻辑层:
      HandleConnMsg:处理连接相关的事务,如心跳机制、用户登陆登出等;
      HandlePlayerMsg:处理玩家相关的事务,如位置同步、得分获取等;
      HandlePlayerEvent:处理玩家事件,某个时间发生时要处理的事情,如玩家登陆登出等;
      PlayerData:指定需要保存到数据库的角色属性,如金币、等级、胜负数等;
      PlayerTempData:指定玩家角色的临时属性,如是否在房间内、是否在战斗中、是否已准备等;

    展开全文
  • Unity3D —— Socket通信(C#)、线程池管理已经用一个队列来管理同时发起的请求,让 Socket 请求和接收异步执行,基本的思路就是引入 多线程 和 异步 这两个概念。 设计思路: 正如上面提及的,我们优化的思路主要两...
  • Unity3d实战之Unity3d网络游戏实战篇(3):网络基础之TCP协议 学习书籍《Unity3d网络游戏实战》 罗培羽著 机械工业出版社 本文是作者在学习过程中遇到的认为值得记录的点,因此引用的代码等资源基本出资罗培羽...
  • Unity3D游戏框架设计

    2018-07-03 20:00:09
    框架部分提供项目中使用的基础设施,包括资源管理、网络通信、UI框架、消息管理、场景管理、数据解析及存取等。1. 资源管理资源管理模块负责按照划分场景的颗粒度将所有游戏资源均打包至AssetBundle并在...
  • 之前Unity3D项目要做跟服务器通信的模块,然后服务器那边的协议是基于http的J'so
  • Unity 网络通信

    2018-07-16 16:51:14
    1,Unity 网络通信(一)Unity Network 初步  
  • [Unity3d]unity与html通信

    2019-07-26 09:54:06
    更多教程请访问: ... 谈谈今天的学习收获,发现了一个好东西,unity与html能够相互通信,意味着我之前学的web开发还能在unity中用得上,哈哈,太happy了!下面简单谈谈通过Unity3D调用HTML网页的脚本...Unity3D浏览...
  • 引言:之前写过一个 demo 案例大致讲解了 Socket 通信的过程,并和自建的服务器完成连接和简单的数据通信,详细的内容可以查看 Unity3D —— Socket通信(C#)。但是在实际项目应用的过程中,这个 demo 的实现方式显得...
  • 框架概述:做了那么久的业务开发,也做了一年多的核心战斗开发,最近想着自己倒腾一套游戏框架,当然暂不涉及核心玩法类型和战斗框架,核心战斗的设计要根据具体的游戏类型而定制,这里只是一些通用的基础系统的框架...
  • Unity3d实战之Unity3d网络游戏实战篇(8):网络管理类ServNet 学习书籍《Unity3d网络游戏实战》 罗培羽著 机械工业出版社 本文是作者在学习过程中遇到的认为值得记录的点,因此引用的代码等资源基本出资罗培羽...
  • 前言:  protobuf是google的一个开源项目,主要...2.制作网络通信协议; 一、资源下载: 1.github源码地址:https://github.com/mgravell/protobuf-net 2.google项目源码下载地址(访问需翻墙):h
  • 转自:https://blog.csdn.net/hiramtan/article/details/72621787开源地址:https://github.com/hiramtan/HiSocket_unityHiSocket_unity如何使用可以从此链接下载最新的unity package: 功能Tcp socketUdp socket可...
  • 2:Unity3D游戏客户端基础框架 一些通用的基础系统的框架搭建,其中包括: UI框架(UGUI+MVC) 消息管理(Message Manager) 网络框架(Socket + Protobuf) 表格数据(Protobuf) 资源管理(Unity5.x的.....
1 2 3 4 5 ... 20
收藏数 1,264
精华内容 505