public MessageInfo AnalyzeMessage(byte[] data, int offset, int length) { var reader = new BinaryReader(new MemoryStream(data, offset, length)); byte header = reader.ReadByte(); if ((header & ResponseTypeFlag) == 0) { byte ifaceOrdinal = header; byte methodOrdinal = reader.ReadByte(); HandlerData handlerData = _handlersData[ifaceOrdinal]; RpcMethodInfo rpcMethodInfo = handlerData.InterfaceMethods[methodOrdinal]; return(new MessageInfo { Type = MessageType.HandlerCall, InterfaceType = RpcInterface.GetRpcInterface(ifaceOrdinal), InterfaceMethodInfo = rpcMethodInfo.MethodInfo, Handler = handlerData.Handler, }); } return(new MessageInfo { Type = MessageType.CallResult, }); }
private void ProcessHandlerCall(BinaryReader reader, byte ifaceOrdinal, object context) { HandlerData handlerData; if (!_handlersData.TryGetValue(ifaceOrdinal, out handlerData)) { Type ifaceType = RpcInterface.GetRpcInterface(ifaceOrdinal); if (ifaceType == null) { throw new ProtocolViolationException("Unknown RPC interface ordinal received: " + ifaceOrdinal); } MethodInfo mi = RpcInterface.GetOrderedMethods(ifaceType)[reader.ReadByte()].MethodInfo; throw new ProtocolViolationException("RPC call received for " + ifaceType.FullName + "." + mi.Name + " which does not have a handler registered."); } byte methodOrdinal = reader.ReadByte(); RpcMethodInfo rpcMethodInfo = handlerData.InterfaceMethods[methodOrdinal]; MethodInfo methodInfo = rpcMethodInfo.MethodInfo; byte callId = 0; if (rpcMethodInfo.HasReturnType) { callId = reader.ReadByte(); } var paramsInfo = methodInfo.GetParameters(); var paramValues = new object[paramsInfo.Length]; for (int i = 0, n = paramValues.Length; i < n; ++i) { paramValues[i] = BinarySerializer.DeserializeParameter(reader, paramsInfo[i]); } var callContext = new HandlerCallContext { HandlerType = handlerData.RpcInterfaceType, Handler = handlerData.Handler, Method = methodInfo, CallId = callId, Context = context, }; if (OnBeforeHandlerCall != null) { OnBeforeHandlerCall(callContext); } callContext.Result = methodInfo.Invoke(handlerData.Handler, paramValues); if (callContext.Result != null && OnDataOut != null) { Type resultFutureType = callContext.Result.GetType(); var stream = new MemoryStream(64); var writer = new BinaryWriter(stream); var header = (byte)(ResponseTypeFlag | callId); writer.Write((byte)header); resultFutureType.GetMethod("Serialize", BindingFlags.NonPublic | BindingFlags.Instance) .Invoke(callContext.Result, new object[] { writer }); OnDataOut(stream.ToArray(), 0, (int)stream.Length); } if (OnAfterHandlerCall != null) { OnAfterHandlerCall(callContext); } }