private void TryReadPackages() { TryNext: if (readCache.Length < 5) { return; } var buffer = readCache.ToArray(); var type = (TcpBsonPackageType)buffer[0]; var size = BitConverter.ToInt32(buffer, 1); if (buffer.Length >= size + 5) { var bodyBuffer = new byte[size]; Array.Copy(buffer, 5, bodyBuffer, 0, size); using (var reader = new BinaryReader(new MemoryStream(bodyBuffer))) { var package = new TcpBsonPackage(); package.Type = type; package.DataType = reader.ReadString(); var byteSize = reader.ReadInt32(); package.DataBytes = reader.ReadBytes(byteSize); Recive(package); } readCache = new MemoryStream(); if (buffer.Length > size + 5) { readCache.Write(buffer, size + 5, buffer.Length - size - 5); readCache.Position = 0; } goto TryNext; } }
private void SendPackageInner(NetworkStream stream, TcpBsonPackage TcpBsonPackage) { var buffer = TcpBsonPackage.ToBytes(); stream.Write(buffer, 0, buffer.Length); stream.Flush(); TcpBsonPackage.Callback?.Invoke(); }
internal void FlushNamedStream(TcpBsonNamedStream TcpBsonNamedStream) { var buffer = TcpBsonNamedStream.GetWriteCacheAndClear(); if (buffer.Length > 0) { var package = new TcpBsonPackage { Type = TcpBsonPackageType.NamedStream, DataType = TcpBsonNamedStream.Name, DataBytes = buffer }; SendPackage(package); } }
private void DoReceiveBson(TcpBsonPackage package) { var dataType = Type.GetType(package.DataType); lock (mJsonHandlers) { foreach (var handler in mJsonHandlers) { if (handler.Type == dataType) { handler.Callback.DynamicInvoke(BsonConvert.DeserializeObject(package.DataBytes, dataType), this); } } } }
private void DoReceiveRequest(TcpBsonPackage package) { var requestType = Type.GetType(package.DataType); var dataType = typeof(TcpBsonRequest <>).MakeGenericType(requestType); var requestBody = BsonConvert.DeserializeObject(package.DataBytes, dataType) as TcpBsonRequest; var handler = mReceiveRequestCallbacks.FirstOrDefault(c => c.URI.Equals(requestBody.URI, StringComparison.OrdinalIgnoreCase) && (c.RequestType == requestType || c.RequestType.IsAssignableFrom(requestType))); var responsePackage = new TcpBsonPackage { Type = TcpBsonPackageType.Response }; object responseBody = null; if (handler == null) { responseBody = new TcpBsonResponse <string> { Id = requestBody.Id, Object = "No handle this request" }; responsePackage.DataType = "ERROR"; return; } try { var response = handler.Callback.DynamicInvoke(requestBody.Object, this); var responseDataType = response != null?response.GetType() : handler.ResponseType; var responseType = typeof(TcpBsonResponse <>).MakeGenericType(responseDataType); var responseData = responseType.GetConstructor(Type.EmptyTypes).Invoke(null); responseType.GetProperty("Id").SetValue(responseData, requestBody.Id, null); responseType.GetProperty("Object").SetValue(responseData, response, null); responsePackage.DataType = responseDataType.AssemblyQualifiedName; responseBody = responseData; } catch (Exception e) { responseBody = new TcpBsonResponse <string> { Id = requestBody.Id, Object = "Handle Exception - " + e.ToString() }; responsePackage.DataType = "ERROR"; } finally { responsePackage.DataBytes = BsonConvert.SerializeObject(responseBody); SendPackage(responsePackage); } }
private void Recive(TcpBsonPackage package) { switch (package.Type) { case TcpBsonPackageType.Command: DoReceiveCommand(Encoding.UTF8.GetString(package.DataBytes)); break; case TcpBsonPackageType.Bson: DoReceiveBson(package); break; case TcpBsonPackageType.Ping: DoPing(); break; case TcpBsonPackageType.NamedStream: DoReceiveNamedStream(package); break; case TcpBsonPackageType.Bytes: DoReceiveBytes(package); break; case TcpBsonPackageType.Request: DoReceiveRequest(package); break; case TcpBsonPackageType.Response: DoReceiveResponse(package); break; case TcpBsonPackageType.CookieSync: Cookies.Sync(package); break; default: break; } }
internal void Sync(TcpBsonPackage package) { var sync = BsonConvert.DeserializeObject <TcpBsonCookieSync>(package.DataBytes); lock (this) { switch (sync.Action) { case TcpBsonCookieSyncAction.Clear: mCookies.Clear(); break; case TcpBsonCookieSyncAction.Add: case TcpBsonCookieSyncAction.Update: mCookies[sync.Name] = sync.Value; break; case TcpBsonCookieSyncAction.Remove: mCookies.Remove(sync.Name); break; } } }
private void DoReceiveResponse(TcpBsonPackage package) { if (package.DataType == "ERROR") { var errorResponse = BsonConvert.DeserializeObject <TcpBsonResponse <string> >(package.DataBytes); var responseCxt = mWaitResponseContexts.FirstOrDefault(r => r.Id == errorResponse.Id); if (responseCxt != null) { responseCxt.SetError(errorResponse.Object); } } else { var responseType = typeof(TcpBsonResponse <>).MakeGenericType(Type.GetType(package.DataType)); var responseBody = BsonConvert.DeserializeObject(package.DataBytes, responseType); var id = (Guid)responseType.GetProperty("Id").GetValue(responseBody, null); var responseCxt = mWaitResponseContexts.FirstOrDefault(r => r.Id == id); if (responseCxt != null) { responseCxt.SetResponse(responseType.GetProperty("Object").GetValue(responseBody, null)); } } }
internal void SendPackage(TcpBsonPackage package) { sendPackageQueue.Enqueue(package); }
private void DoReceiveNamedStream(TcpBsonPackage package) { var namedStream = GetNamedStream(package.DataType); namedStream.OnDataReceive(package.DataBytes); }
private void DoReceiveBytes(TcpBsonPackage package) { mBytesHandlers.ForEach(callback => callback(package.DataBytes, this)); }