public void TestPrepare_SetAsNotification_SendingBufferAndSessionAreSet() { var target = new ClientRequestContext(); target.SetNotification("A", (_0, _1) => { }); var oldSessionId = target.SessionId; target.Prepare(true); Assert.That(target.SendingBuffer.All(segment => segment.Array != null), Is.Not.Null); Assert.That(target.BufferList, Is.SameAs(target.SendingBuffer)); }
public void TestPrepare_SetAsNotification_SendingBufferAndSessionAreSet() { var target = new ClientRequestContext(); target.SetNotification( "A", ( _0, _1 ) => { } ); var oldSessionId = target.SessionId; target.Prepare( true ); Assert.That( target.SendingBuffer.All( segment => segment.Array != null ), Is.Not.Null ); Assert.That( target.BufferList, Is.SameAs( target.SendingBuffer ) ); }
/// <summary> /// Sends a request or notification message with the specified context. /// </summary> /// <param name="context">The context information.</param> /// <exception cref="ArgumentNullException"> /// <paramref name="context"/> is <c>null</c>. /// </exception> /// <exception cref="ArgumentException"> /// <paramref name="context"/> is not bound to this transport. /// </exception> /// <exception cref="ObjectDisposedException"> /// This instance has been disposed. /// </exception> /// <exception cref="InvalidOperationException"> /// This instance is in shutdown. /// Or the message ID or session ID is duplicated. /// </exception> /// <exception cref="RpcException"> /// Failed to send request or notification to the server. /// </exception> public void Send(ClientRequestContext context) { if (context == null) { throw new ArgumentNullException("context"); } if (!Object.ReferenceEquals(context.BoundTransport, this)) { throw new ArgumentException("Context is not bound to this object.", "context"); } this.VerifyIsNotDisposed(); if (this.IsClientShutdown) { throw new InvalidOperationException("This transport is in shutdown."); } Contract.EndContractBlock(); if (this.IsServerShutdown) { throw new RpcErrorMessage(RpcError.TransportError, "Server did shutdown socket.", null).ToException(); } context.Prepare(this.CanUseChunkedBuffer); if (context.MessageType == MessageType.Request) { if (!this._pendingRequestTable.TryAdd(context.MessageId.Value, context.RequestCompletionCallback)) { throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, "Message ID '{0}' is already used.", context.MessageId)); } } else { if (!this._pendingNotificationTable.TryAdd(context.SessionId, context.NotificationCompletionCallback)) { throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, "Session ID '{0}' is already used.", context.MessageId)); } } if (MsgPackRpcClientProtocolsTrace.ShouldTrace(MsgPackRpcClientProtocolsTrace.SendOutboundData)) { var socket = this.BoundSocket; MsgPackRpcClientProtocolsTrace.TraceEvent( MsgPackRpcClientProtocolsTrace.SendOutboundData, "Send request/notification. {{ \"SessionID\" : {0}, \"Socket\" : 0x{1:X}, \"RemoteEndPoint\" : \"{2}\", \"LocalEndPoint\" : \"{3}\", \"Type\" : \"{4}\", \"MessageID\" : {5}, \"Method\" : \"{6}\", \"BytesTransferring\" : {7} }}", context.SessionId, GetHandle(socket), GetRemoteEndPoint(socket, context), GetLocalEndPoint(socket), context.MessageType, context.MessageId, context.MethodName, context.SendingBuffer.Sum(segment => ( long )segment.Count) ); } // Because exceptions here means client error, it should be handled like other client error. // Therefore, no catch clauses here. ApplyFilters(this._afterSerializationFilters, context); if (this.Manager.Configuration.WaitTimeout != null) { context.Timeout += this.OnSendTimeout; context.StartWatchTimeout(this.Manager.Configuration.WaitTimeout.Value); } this.SendCore(context); }