自定义.NET Remoting IServerChannelSink

时间:2011-08-17 15:22:55

标签: c# .net remoting .net-remoting

我有一个使用.NET Remoting通信的客户端 - 服务器应用程序。出于身份验证的原因,我必须编写自定义IClientChannelSink以将会话cookie插入到HTTP请求中。 在服务器端,我还编写了一个自定义IServerChannelSink来从HTTP请求标头中读取服务器所需的一些信息。

客户端工作正常,但在服务器端我总是收到以下错误:

  

System.ArgumentNullException未被用户代码Message = No处理   在调用DispatchChannelSink之前,消息被反序列化。   参数名称:requestMsg Source = mscorlib ParamName = requestMsg
  堆栈跟踪:          在   System.Runtime.Remoting.Channels.DispatchChannelSink.ProcessMessage(IServerChannelSinkStack   sinkStack,IMessage requestMsg,ITransportHeaders requestHeaders,   流requestStream,IMessage& responseMsg,ITransportHeaders&   responseHeaders,Stream& responseStream)          在   MyAuthentication.MyServerChannelSink.ProcessMessage(IServerChannelSinkStack   sinkStack,IMessage requestMsg,ITransportHeaders requestHeaders,   流requestStream,IMessage& responseMsg,ITransportHeaders&   responseHeaders,Stream& responseStream)in   C:\ Dev \ MyAuthentication \ MyServerChannelSink.cs:第82行          在   System.Runtime.Remoting.Channels.BinaryServerFormatterSink.ProcessMessage(IServerChannelSinkStack   sinkStack,IMessage requestMsg,ITransportHeaders requestHeaders,   流requestStream,IMessage& responseMsg,ITransportHeaders&   responseHeaders,Stream& responseStream)          在   System.Runtime.Remoting.Channels.Http.HttpServerTransportSink.ServiceRequest(对象   州)          在   System.Runtime.Remoting.Channels.SocketHandler.ProcessRequestNow()
  的InnerException:

我的“ProcessMessage”-method看起来如下:

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;
}

如果有人能告诉我什么是错的,那会很棒。

3 个答案:

答案 0 :(得分:2)

在某些情况下,requestMsg参数可以是 空值。所以你必须处理这些案件。例如,另一个服务器通道接收器 正在调用您的ProcessMessage函数,并将requestMsg设置为null!

编辑:提供样本的链接。 以下是服务器接收器示例的链接:Server Sink

答案 1 :(得分:0)

我已经解决了我的问题。由于我不使用通道接收器进行任何序列化,我也不想自己处理消息反序列化。以下实现工作正常:

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;
}

答案 2 :(得分:0)

创建服务器频道

TcpServerChannel oTcpChannel =
    new TcpServerChannel(oTcpChannelConfiguration, oServerSinkProvider, oAuthority);

您可以设置oServerSinkProvider = null,系统将支持默认接收器提供程序。您也可以指定自己的格式化程序,例如TCP通道的soap格式化程序或http通道的二进制格式化程序:SoapServerFormatterSinkProviderBinaryServerFormatterSinkProvider

但是,如果您支持自己的服务器接收器,则必须实现自己的格式化程序。您可以在函数IServerChannelSinkProvider.Next的set部分中执行此操作:

  set
  {
    if ( value != null )
    {
      nextProvider = new BinaryServerFormatterSinkProvider ();
      nextProvider.Next = value;
    }
    else
    {
      nextProvider = value;
    };
  }

然后,下一个提供程序在这种情况下执行fomatting,二进制格式化。