public TMessage CallMethod <TMessage, TBuilder>(string method, IMessageLite request, IBuilderLite <TMessage, TBuilder> response) where TMessage : IMessageLite <TMessage, TBuilder> where TBuilder : IBuilderLite <TMessage, TBuilder> { //obviously you could do anything here... create a logging adapter, forward messages to another server, whatever. using (RpcCallContext.Current.Impersonate()) { //do some test to see if the use is allowed... WindowsIdentity userId = (WindowsIdentity)RpcCallContext.Current.ClientUser; Assert.IsFalse(userId.IsAnonymous); Assert.IsFalse(userId.IsGuest); //then, call the final target: return(_next.CallMethod(method, request, response)); } }
TMessage IRpcDispatch.CallMethod <TMessage, TBuilder>(string method, IMessageLite request, IBuilderLite <TMessage, TBuilder> response) { int size = request.SerializedSize; if (size < multiPartThreshold) { return(next.CallMethod(method, request, response)); } else { ByteString transaction = ByteString.CopyFrom(Guid.NewGuid().ToByteArray()); byte[] requestBytes = request.ToByteArray(); RpcMultiPartRequest.Types.RpcMessageStatus status = RpcMultiPartRequest.Types.RpcMessageStatus.CONTINUE; try { int total = requestBytes.Length; int amt = multiPartThreshold - 1024; //reserved for header RpcMultiPartResponse mpr = RpcMultiPartResponse.DefaultInstance; for (int pos = 0; pos < total; pos += amt) { amt = Math.Min(amt, total - pos); status = (pos + amt) < total ? status : RpcMultiPartRequest.Types.RpcMessageStatus.COMPLETE; mpr = next.CallMethod(".multi", RpcMultiPartRequest.CreateBuilder() .SetTransactionId(transaction) .SetMethodName(method) .SetMessageStatus(status) .SetCurrentPosition(pos) .SetTotalBytes(total) .SetBytesSent(amt) .SetPayloadBytes(ByteString.CopyFrom(requestBytes, pos, amt)) .Build(), RpcMultiPartResponse.CreateBuilder() ); if (!mpr.Continue) { throw new InvalidDataException("The operation was canceled by the server."); } } if (!mpr.HasResponseBytes) { throw new InvalidDataException("The server did not provide a response."); } return(response.MergeFrom(mpr.ResponseBytes.ToByteArray(), extensions).Build()); } catch { if (status == RpcMultiPartRequest.Types.RpcMessageStatus.CONTINUE) { try { next.CallMethod(".multi", RpcMultiPartRequest.CreateBuilder() .SetTransactionId(transaction) .SetMessageStatus(RpcMultiPartRequest.Types.RpcMessageStatus.CANCEL) .Build(), RpcVoid.CreateBuilder() ); } catch (Exception e) { Trace.TraceWarning("Unable to cancel multi-part message: {0}, error = {1}", transaction, e); } } throw; } } }