Skip to content

Instantly share code, notes, and snippets.

@dulm
Created May 18, 2015 03:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dulm/d1dd04be532991f9a1cd to your computer and use it in GitHub Desktop.
Save dulm/d1dd04be532991f9a1cd to your computer and use it in GitHub Desktop.
msgpack crash
using System;
using System.IO;
using System.Threading;
using System.Collections.Generic;
using System.Threading.Tasks;
using MsgPack;
using MsgPack.Serialization;
namespace fight_server
{
public class RecvMsgHead
{
public string cmd_id;
}
public class RecvMsgDes
{
public RecvMsgHead head;
public object packet;
}
public class SendMsgHead
{
public string cmd_id{ get; set; }
}
public class SendMsgDes
{
public SendMsgHead head{ get; set; }
public byte[] packet{ get; set; }
}
public class MsgPackMgrException : Exception
{
public MsgPackMgrException(string msg)
: base(msg)
{
}
}
public class MsgPackMgr
{
private static MsgPackMgr _ins;
public static MsgPackMgr ins {
get {
if(_ins == null)
{
Console.WriteLine("msgpackmgr inssssssss");
_ins = new MsgPackMgr();
}
return _ins;
}
}
/*
public static Dictionary<string, Func<byte[], object> > dic = new Dictionary<string, Func<byte[], object> >();
public static Dictionary<string, IMessagePackSingleObjectSerializer> dic2 = new Dictionary<string, IMessagePackSingleObjectSerializer>();
public MsgPackMgr ()
{
dic ["Person"] = (byte_arr) => {
var ms = new MemoryStream (byte_arr);
var serializer = MessagePackSerializer.Get< proto.Person > ();
var p = serializer.Unpack (ms);
return p;
};
dic2["Person"] = MessagePackSerializer.Get< proto.Person > ();
}
public object desri(string cmd_id, byte[] sri_packet)
{
Func<byte[], object> func = dic [cmd_id];
if (func == null)
{
throw new MsgPackMgrException(string.Format("No desialize func for cmd_id {}", cmd_id));
}
return func (sri_packet);
}
public object desri2(string cmd_id, byte[] sri_packet)
{
var serializer = dic2 ["Person"];
var ms = new MemoryStream (sri_packet);
var p = serializer.Unpack (ms);
return p;
}*/
static Dictionary<string, IMessagePackSingleObjectSerializer> _sri_map = new Dictionary<string, IMessagePackSingleObjectSerializer>();
public static IMessagePackSingleObjectSerializer get_srier(string cmd_id)
{
lock(_sri_map)
{
IMessagePackSingleObjectSerializer serializer;
string key = "fight_server.proto." + cmd_id;
if (_sri_map.ContainsKey (key) == false) {
//Thread.Sleep (1);
Console.WriteLine ("new srier type");
var context = new SerializationContext();
context.SerializationMethod = SerializationMethod.Map;
context.CompatibilityOptions.PackerCompatibilityOptions = PackerCompatibilityOptions.None;
var type = Type.GetType (key);
serializer = MessagePackSerializer.Get (type, context);
_sri_map.Add (key, serializer);
Console.WriteLine ("new srier type end");
} else {
serializer = _sri_map [key];
}
return serializer;
}
}
public object desri(string cmd_id, byte[] sri_packet)
{
Console.WriteLine ("desri");
var serializer = get_srier(cmd_id);
var ms = new MemoryStream (sri_packet);
var p = serializer.Unpack (ms);
return p;
}
public RecvMsgDes desri_des(byte[] s_packet_des)
{
/*
//simulate no desri_des, to exclude the crash reason.
RecvMsgDes rd2 = new RecvMsgDes {
head = new RecvMsgHead{cmd_id = "Person"},
packet = new proto.Person{
id = 1,
name = "lqk",
},
};
return rd2;*/
/*
//静态方式解码
class Testa{
public string cmd_id;
public byte[] packet;
}
var serializer2 = MessagePackSerializer.Get<Testa> ();
var ms2 = new MemoryStream (s_packet_des);
var aa = serializer2.Unpack(ms2);
*/
try{
lock(typeof(MsgPackMgr))
{
Console.WriteLine ("desri_des");
//head, 动态取属性
var ms = new MemoryStream (s_packet_des);
ms.Position = 0;
var obj = Unpacking.UnpackObject (ms);
var packet_des = obj.AsDictionary ();
var cmd_id = packet_des ["cmd_id"].AsString();
Console.WriteLine ("desri_des head");
//body, 生成到类
var encode_packet = packet_des ["packet"].AsBinary();
ms = new MemoryStream (encode_packet);
var packet = MsgPackMgr.ins.desri (cmd_id, encode_packet);
RecvMsgDes rd = new RecvMsgDes {
head = new RecvMsgHead{cmd_id = cmd_id},
packet = packet,
};
return rd;
}
}
finally{
Console.WriteLine ("desri_des end");
Console.Out.Flush();
}
}
public byte[] sri(string cmd_id, object obj)
{
Console.WriteLine ("sri");
var serializer = get_srier(cmd_id);
var ms = new MemoryStream ();
serializer.Pack(ms, obj);
var sri_packet = ms.ToArray();
return sri_packet;
}
public byte[] sri_des(string cmd_id, object obj)
{
//return new byte[10];//simulate no serialize, to exculde the crash reason
lock(typeof(MsgPackMgr))
{
Console.WriteLine ("sri_des");
SendMsgDes smd = new SendMsgDes {
head = new SendMsgHead{
cmd_id = cmd_id,
},
packet = sri(cmd_id, obj),
};
var context = new SerializationContext();
context.SerializationMethod = SerializationMethod.Map;
context.CompatibilityOptions.PackerCompatibilityOptions = PackerCompatibilityOptions.None;
var serializer = MessagePackSerializer.Get<SendMsgDes>(context) ;
var ms = new MemoryStream ();
serializer.Pack(ms, smd);
var s_packet_des = ms.ToArray ();
return s_packet_des;
}
/*
var dic = new Dictionary<string, object>();
dic ["cmd_id"] = cmd_id;
dic ["packet"] = sri (cmd_id, obj);
var ms = new MemoryStream ();
//序列化成list了,所以是packer , unpacker用,手动在类内序列化,可以节省key的空间
SerializationContext.Default.SerializationMethod = SerializationMethod.Map;
var packer = Packer.Create (ms);
packer.PackDictionary (dic);
//var mpo = MessagePackObject.FromObject (obj);
//var s_packet_des2 = mpo.AsBinary ();
//packer.PackObject (obj);
byte[] s_packet_des = ms.ToArray ();
return s_packet_des;*/
}
}
namespace proto
{
public class Prop{
public string name {
get;
set;
}
public int id {
get;
set;
}
}
public class Person{
public string name {
get;
set;
}
public int id {
get;
set;
}
public Prop[] prop_arr {
get;
set;
}
}
}
class MainClass
{
public static void Main (string[] args)
{
Console.WriteLine ("Hello World!");
//test
TaskFactory _task_factory = new TaskFactory();
while (true) {
_task_factory.StartNew (() => {
proto.Person person = new proto.Person{
id = 1,
name = "lqk",
prop_arr = new proto.Prop[1]{
new proto.Prop{
id = 1,
name = "lqk",
}
}
};
MsgPackMgr.ins.sri_des("Person", person);
});
_task_factory.StartNew (() => {
proto.Person p = new proto.Person{
id = 1,
name = "lqk",
prop_arr = new proto.Prop[1]{
new proto.Prop{
id = 1,
name = "lqk",
}
}
};
var sri_packet = MsgPackMgr.ins.sri_des("Person", p);
MsgPackMgr.ins.desri("Person", sri_packet);
});
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment