首先对 jsbinding先有个认识,不得不承认,还不够成熟,有些语法还有问题,但是解决方案本人认为大部分问题都是可以绕过去的,能实现传说中的效果,用C#写热更代码
jsb的作者地址,群里的浅唱
http://www.cnblogs.com/answerwinner/p/4469021.html
基础原理就不再多说了
目前工具比较完善的版本是PureJSB
github地址
https://github.com/linkabox/PureJSB
作者是群里的linka
这些都是基础工具和功能,还有一点就是关于网络协议的热更方面,配置数据和网络协议可以动态添加和修改,才是合格的热更方案
http://www.cnblogs.com/zyc-it/p/4881026.html
下边着重分析下protobuff的使用以及我们项目的进一步处理,是基于群里夜莺的思路开发的
首先介绍下夜莺的思路,这是示例程序中的例子协议类,代表一个可发送的结构体,有两个成员 serverId 和 charId
<public class ExampleMessage : MessageParent
{
public int serverId;
public int charId;
public override string GetProToString()
{
return @"package User;
message UserProto{
required int32 id = 1;
required int32 status = 2;
required string name = 3;
required string pwdMd5 = 4;
required string regTime = 5;
message ServerChar{
required int32 serverId = 1;
required int32 charId = 2;
}
repeated ServerChar serverChars = 6;
}";
}
public override string GetMessageName()
{
return "User.UserProto.ServerChar";
}
}
然后看一下这个类是如何序列化的,这个类继承自MessageParent
public class MessageParent
{
public virtual string GetMessageName() {
return "";
}
public virtual string GetProToString()
{
return "";
}
public virtual string Encode()
{
UnityEngine.Debug.LogError("data>>" + JSON.stringify(this));
string rawString = ProtoBufferWrap.Encode(GetProToString(), GetMessageName(), this);
return rawString;
}
public virtual object Decode(string data) {
UnityEngine.Debug.LogError("data>>" + data);
object _object =ProtoBufferWrap.Decode(GetProToString(), GetMessageName(), data);
UnityEngine.Debug.LogError("data>>" + JSON.stringify(_object));
return _object;
}
}
可以看到这个类是没有做序列化的事情,只是把重载后具有实际意义的两个参数传递给ProtoBufferWrap类,再看下这个类
public class ProtoBufferWrap
{
[JsMethod(Code = @"var ProtoBuf = dcodeIO.ProtoBuf,
Message = ProtoBuf.protoFromString(ProtoString).build(MessageName);
Message = new Message(JSON.parse(JSON.stringify(dataInstance)));
return Message.encode().toBase64();")]
public static string Encode(string ProtoString, string MessageName, object dataInstance)
{
return (string) null;
}
[JsMethod(Code = @"var ProtoBuf = dcodeIO.ProtoBuf,
Bytebuffer=dcodeIO.ByteBuffer,
Message = ProtoBuf.protoFromString(ProtoString).build(MessageName);
return Message.decode(Bytebuffer.fromBase64(dataString));")]
public static JsObject Decode(string ProtoString, string MessageName, string dataString)
{
return (JsObject)null;
}
}
然后是用法
ExampleMessage example =new ExampleMessage();
example.charId = 100;
example.serverId = -100;
// 这个encode的出来的message 其实是base64string ,就可以传给c#,用Convert.FromBase64String(message) 转换成byte[],然后发送给soket 就可以了;
string message = example.Encode();
UnityEngine.Debug.LogError("example encode 之前的json 是" + JSON.stringify(example));
UnityEngine.Debug.LogError("example encode 之后的数据是message");
ExampleMessage example2 = new ExampleMessage();
ExampleMessage ExampleMessageDecode = (ExampleMessage)(example2.Decode(message));
UnityEngine.Debug.LogError("example decode 之后的json 是" + JSON.stringify(ExampleMessageDecode));
可以看到这个类是真正的做序列化操作的,利用sharpkit的一些功能,写了通过的js代码实现转换
注意,以上三个类都是转换为js的
下边开始分析过程,一个类要能够序列化,需要三个参数
1.C#类本身,如例子中的ExampleMessage,成员名字与.proto文件中定义的要一致
2.协议字符串,即protobuff中的通用的.proto中的内容,需要注意,不支持import,所以需要把依赖的内容写到一起
3.协议的唯一标识,函数GetMessageName中返回的字符串
这个方案有一定的局限性,包括protoName的管理,protoString无法使用写好的.proto文件等,如果要解决这个问题,需要写基于.proto文件的C#类
的生成工具,即便如此,因为生成的C#类的特殊性,与protobuff-net生成的类差别较大,无法实现C#代码开发js代码发布的终极目标,但已经是具有
突破意义的第一步!
为了防止出现太长不看系列,我们基于该方案的改动分享作为下一篇分析继续~请原谅我先发出去了,后续的马上补齐