Search code examples
c#.netremoting.net-remoting

Custom .NET Remoting IServerChannelSink


i have a client-server application which uses .NET Remoting communication. For authentication reasons i had to write a custom IClientChannelSink to insert a session cookie into the HTTP-requests. On the server side i also wrote a custom IServerChannelSink to read some information the server needs from the HTTP-request headers.

The client side works fine, but on the server side i always get the following error:

System.ArgumentNullException was unhandled by user code Message=No message was deserialized prior to calling the DispatchChannelSink. Parameter name: requestMsg Source=mscorlib ParamName=requestMsg
StackTrace: at System.Runtime.Remoting.Channels.DispatchChannelSink.ProcessMessage(IServerChannelSinkStack sinkStack, IMessage requestMsg, ITransportHeaders requestHeaders, Stream requestStream, IMessage& responseMsg, ITransportHeaders& responseHeaders, Stream& responseStream) at MyAuthentication.MyServerChannelSink.ProcessMessage(IServerChannelSinkStack sinkStack, IMessage requestMsg, ITransportHeaders requestHeaders, Stream requestStream, IMessage& responseMsg, ITransportHeaders& responseHeaders, Stream& responseStream) in C:\Dev\MyAuthentication\MyServerChannelSink.cs:line 82 at System.Runtime.Remoting.Channels.BinaryServerFormatterSink.ProcessMessage(IServerChannelSinkStack sinkStack, IMessage requestMsg, ITransportHeaders requestHeaders, Stream requestStream, IMessage& responseMsg, ITransportHeaders& responseHeaders, Stream& responseStream) at System.Runtime.Remoting.Channels.Http.HttpServerTransportSink.ServiceRequest(Object state) at System.Runtime.Remoting.Channels.SocketHandler.ProcessRequestNow()
InnerException:

My "ProcessMessage"-methodlooks as follows:

public ServerProcessing ProcessMessage(IServerChannelSinkStack sinkStack, IMessage requestMsg, ITransportHeaders requestHeaders, Stream requestStream, out IMessage responseMsg, out ITransportHeaders responseHeaders, out Stream responseStream)
{
    // Pre-processing before sending the message to the next sink in the chain
    object state = null;
    ProcessRequest(requestMsg, requestHeaders, ref requestStream, ref state);

    /* Call the next sink in the chain */
    sinkStack.Push(this, state);
    ServerProcessing serverProcessing = this.NextChannelSink.ProcessMessage(sinkStack, requestMsg, requestHeaders, requestStream, out responseMsg, out responseHeaders, out responseStream);

    // Processing from sink further in the chain has completed. Now do any post-processing before returning to the previous sink in the chain.
    ProcessResponse(null, responseHeaders, ref responseStream, state);

    return serverProcessing;
}

Would be great if anyone can tell me whats wrong.


Solution

  • I've solved my problem. Since i don't use the channel sinks to do any serialization i also don't want to handle the message deserialization by myself. The following implemention works fine:

    public ServerProcessing ProcessMessage(IServerChannelSinkStack sinkStack, IMessage requestMsg, ITransportHeaders requestHeaders, Stream requestStream, out IMessage responseMsg, out ITransportHeaders responseHeaders, out Stream responseStream)
    {
        // Pre-processing before sending the message to the next sink in the chain
        object state = null;
        ProcessRequest(requestMsg, requestHeaders, ref requestStream, ref state);
    
        ServerProcessing serverProcessing;
        if (requestMsg != null)
        {
            /* Call the next sink in the chain */
            sinkStack.Push(this, state);
            serverProcessing = this.NextChannelSink.ProcessMessage(sinkStack, requestMsg, requestHeaders, requestStream, out responseMsg, out responseHeaders, out responseStream);
            sinkStack.Pop(this);
        }
        else
        {
            responseMsg = null;
            responseHeaders = null;
            responseStream = null;
            serverProcessing = ServerProcessing.Complete;
        }
    
        // Processing from sink further in the chain has completed. Now do any post-processing before returning to the previous sink in the chain.
        ProcessResponse(null, responseHeaders, ref responseStream, state);
    
        return serverProcessing;
    }