// 构造器,需要指明数据映射工具 public BinaryFilePersistence(string dirPath, Action <T, IWriteableBuffer> data2BufferHandler, Func <IReadableBuffer, T> buff2DataHandler) : base((T obj) => { WriteBuffer buff = new WriteBuffer(); data2BufferHandler(obj, buff); return(buff.Data); }, (byte[] buff) => { RingBuffer data = new RingBuffer(); if (buff == null) { return(buff2DataHandler(null)); } else { data.Write(buff, 0, buff.Length); return(buff2DataHandler(data)); } } ) { dir = dirPath; hb2d = (byte[] buff) => { RingBuffer data = new RingBuffer(); if (buff == null) { return(buff2DataHandler(null)); } else { data.Write(buff, 0, buff.Length); return(buff2DataHandler(data)); } }; if (!Directory.Exists(dir)) { Directory.CreateDirectory(dir); } }
// 创建当前消息的应答 public IWriteableBuffer BeginResponse(long responseID) { WriteBuffer buff = null; if (WriteBufferPool.Count > 0) { buff = WriteBufferPool.Dequeue() as WriteBuffer; buff.Clear(); } else { buff = new WriteBuffer(true); } buff.IsUsing = true; buff.Reserve(sizeof(int)); buff.Write(responseID); return(buff); }
// 发送消息给指定连接列表 public static void Broadcast(string op, string toComponent, Action <IWriteableBuffer> fun, Connection[] toConnection, Connection excludeConn) { WriteBuffer tmpBuff = new WriteBuffer(true); if (fun != null) { fun(tmpBuff); } foreach (Connection c in toConnection) { if (c == null || c == excludeConn) { continue; } IWriteableBuffer buff = c.BeginSend(toComponent); buff.Write(op); buff.Write(tmpBuff.Data, 0, tmpBuff.Available); c.End(buff); } }
// 消息请求结束或发送 public void End(NetConnection nc, IWriteableBuffer buff) { WriteBuffer wb = (buff as WriteBuffer); // 如果没有被使用说明这个buff已经被还回 // 说明有什么地方调用了多次end if (!wb.IsUsing) { throw new Exception("call end more than once"); } int len = buff.Available - sizeof(int); wb.Unreserve(0, BitConverter.GetBytes(IPAddress.HostToNetworkOrder(len))); // if it's a request long no = -wb.PeekLong(sizeof(int)); CallbackNode cbn; if (callbacks.TryGetValue(no, out cbn)) { cbn.nc = nc; } // 长度信息不加密,余下加密 for (int i = sizeof(int); i < wb.Available; i++) { wb.Data[i] = nc.Encrypt(wb.Data[i]); } nc.SendData(wb.Data, 0, wb.Available); WriteBufferPool.Enqueue(wb); wb.IsUsing = false; if (OnSendMsg != null) { OnSendMsg(len); } }
// 在指定 id 的连接上发送请求 public IWriteableBuffer BeginRequest(string componentName, Action <IReadableBuffer> cb, Action <bool> expiredProcess) { WriteBuffer buff = null; if (WriteBufferPool.Count > 0) { buff = WriteBufferPool.Dequeue() as WriteBuffer; buff.Clear(); } else { buff = new WriteBuffer(true); } buff.IsUsing = true; buff.Reserve(sizeof(int)); long no = p(); buff.Write(no); buff.Write(componentName); // 记录回调处理句柄 CallbackNode cbn = new CallbackNode(); cbn.time = Utils.NowSecond; cbn.cb = cb; callbacks[-no] = cbn; if (expiredProcess != null) { usrDefinedExpireProcess[-no] = expiredProcess; } return(buff); }
// 在指定 id 的连接上开始发送消息 public IWriteableBuffer BeginSend(string componentName) { WriteBuffer buff = null; if (WriteBufferPool.Count > 0) { buff = WriteBufferPool.Dequeue() as WriteBuffer; buff.Clear(); } else { buff = new WriteBuffer(true); } buff.IsUsing = true; buff.Reserve(sizeof(int)); long no = p(); buff.Write(no); buff.Write(componentName); return(buff); }
// 消息请求结束或发送 public void End(NetConnection nc, IWriteableBuffer buff) { WriteBuffer wb = (buff as WriteBuffer); // 如果没有被使用说明这个buff已经被还回 // 说明有什么地方调用了多次end if (!wb.IsUsing) { throw new Exception("call end more than once"); } // 检查是否和上一条消息完全一致 var identifyWithLastOne = false; var rawData = wb.Data; var rawDataLen = wb.Available; if (nc.LastSent != null && nc.LastSent.Available == rawDataLen) { identifyWithLastOne = true; for (var i = 0; i < rawDataLen; i++) { if (nc.LastSent.Data[i] != rawData[i]) { identifyWithLastOne = false; break; } } } if (identifyWithLastOne) { nc.SendData(TrueBytes, 0, TrueBytes.Length); } else { wb.Unreserve(0, FalseByte); int len = buff.Available - sizeof(bool) - sizeof(int); wb.Unreserve(sizeof(bool), BitConverter.GetBytes(IPAddress.HostToNetworkOrder(len))); // if it's a request long no = -wb.PeekLong(FalseByte.Length + sizeof(int)); CallbackNode cbn; if (callbacks.TryGetValue(no, out cbn)) { cbn.nc = nc; } // 长度信息不加密,余下加密 for (int i = sizeof(int); i < wb.Available; i++) { wb.Data[i] = nc.Encrypt(wb.Data[i]); } nc.SendData(wb.Data, 0, wb.Available); Dealloc(nc.LastSent); nc.LastSent = wb; } wb.IsUsing = false; }