怎么办,这很尴尬,为啥呢,因为kbe的某些原因让我放弃了使用它所以本打算继续更新的,说一下原因:
在DAY1中我希望kbe能够开启一个http服务,并让php端做一个web请求将消息传递给对应的用户,可是这个http服务我是写起来了,发送消息的函数也写出来(花了不少时间,kbe的注释和文档都不多,特别是kbe把BaseHttpServer这个python库另外弄了个名字,用http.server import as 才导入成功)尴尬的就是http服务和发消息的函数怎么也放不到一起:
1.一旦某个class不继承自KBEngine.Base,那么他就无法访问KBEngine的几乎所有静态函数、属性,就无法获取到对应用户的mailbox完成消息发送
2.一旦继承KBEgine.Base,你就做不了HTTP 服务,因为你的handler必须继承baseHandler,你继承不了,且即使你继承到baseHandler去访问KBEgine.Base的mailbox之类的又回到刚的死逻辑之中
3.系统库的HTTP服务会阻塞进程,这个文档还是写了,不过替代框架太麻烦,且调试太不方便,且语法太熟悉,且…………虽然我想说一万个且,只能说明我无能啊…………
当然论坛和官网当中也有人反应类似的问题,例如第三方接口访问KBE的成员/属性问题,不过看起来好像并没有现成的解决方案,最后的最后。。。我放弃了
然后呢~~我自己老老实实写了一个消息服务器(基于socket ,with WPF .net 4.5+)以及消息协议
消息协议采用http://msgpack.org/ 基本上支援所有的语言,因此实际上我这个消息服务器可以服务任何类型的客户端,不管你啥平台啥语言
1.0版协议(还没名字呢)规定:
1.BasePack代表发送的包,BaseAckPack代表回执包,BaseAckPack继承自BasePack
2.每个Pack长度为1024字节,且第0~4字节转换成int代表pack类型, BasePack及其子类从1.2.3...10... BaseAckPack 及其子类从1001,1002,1003...1010...(有考虑负数,其实应该也ok)
为啥这样做? 这里很奇特,你在把这1024个字节用msgpack转成对象之前,你并不知道这个pack是哪个对象,你不能统一按某一个特定的对象去转,比如LoginPack比BasePack只多了2个属性,你在不知道它是一个LoginPack还是一个BasePack之前,你无法拆开他,你按任何一种来拆开都有可能出错(属性多了或少了,熟悉iOS 的KVC的应该很清楚),所以必须先把前面4个字节腾出来,可选的,第5~8个字节放长度(mespack可以长度大于内容拆开没问题),读8个字节之后再读剩下的1016(当然不一定每个包一定得是1024,可以更大,毕竟我目前够用了)个字节
using System;
//send包
namespace Packs
{
//基础包
public class BasePack<T>
{
public int packType;
public int fromId;
public int toId;
public int messageId;
//将基本包转bytes
public byte[] PackToBytes()
{
var encode = MsgPack.Serialization.MessagePackSerializer.Get<T>();
byte[] packContent = encode.PackSingleObject(this);
byte[] type = BasePack.intToBytes(this.packType);
byte[] len = BasePack.intToBytes(packContent.Length);
int lenth = packContent.Length;
byte[] dest = new byte[1024];
//第一个int空间:类型
Buffer.BlockCopy(type, 0, dest, 0, type.Length);
//第二个int空间:长度
Buffer.BlockCopy(len, 0, dest, type.Length, len.Length);
//剩余空间:包内容
Buffer.BlockCopy(packContent, 0, dest, type.Length+len.Length, packContent.Length);
Console.WriteLine("打包pack,类型:" + this.packType + "长度:" + packContent.Length);
return dest;
}
//将bytes转回基本包
public static T BytesToPack(byte[] bytes)
{
var encode = MsgPack.Serialization.MessagePackSerializer.Get<T>