【问题标题】:Custom .NET Remoting IServerChannelSink自定义 .NET 远程处理 IServerChannelSink
【发布时间】:2011-08-17 15:22:55
【问题描述】:

我有一个使用 .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,流和响应流) 在 MyAuthentication.MyServerChannelSink.ProcessMessage(IServerChannelSinkStack sinkStack,IMessage requestMsg,ITransportHeaders requestHeaders, 流 requestStream、IMessage& responseMsg、ITransportHeaders& responseHeaders, Stream& responseStream) 中 C:\Dev\MyAuthentication\MyServerChannelSink.cs:第 82 行 在 System.Runtime.Remoting.Channels.BinaryServerFormatterSink.ProcessMessage(IServerChannelSinkStack sinkStack,IMessage requestMsg,ITransportHeaders requestHeaders, 流 requestStream、IMessage& responseMsg、ITransportHeaders& responseHeaders,流和响应流) 在 System.Runtime.Remoting.Channels.Http.HttpServerTransportSink.ServiceRequest(对象 状态) 在 System.Runtime.Remoting.Channels.SocketHandler.ProcessRequestNow()
内部异常:

我的“ProcessMessage”-方法如下:

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

如果有人能告诉我出了什么问题,那就太好了。

【问题讨论】:

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


    【解决方案1】:

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

    编辑:提供示例链接。 这是服务器接收器示例的链接:Server Sink

    【讨论】:

    • 您有任何示例代码如何处理这些情况吗?我在网络上找不到任何 IClientChannelSink 的参考实现。我的 IClientChannelSink 实现应该只从 HTTP-header 中读取一些值,但不能以任何方式更改请求消息。
    • 在 MSDN 中有一个示例实现。但似乎和我的实现类似msdn.microsoft.com/en-us/library/…
    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

      通过创建您的服务器频道

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

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

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

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

      然后下一个提供者完成格式化工作,在这种情况下为二进制格式。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-12-24
        • 2010-10-11
        相关资源
        最近更新 更多