通过 .NET 远程处理将流传递给方法

Posted

技术标签:

【中文标题】通过 .NET 远程处理将流传递给方法【英文标题】:Passing a stream to a method via .NET remoting 【发布时间】:2013-11-27 13:58:09 【问题描述】:

让我简单描述一下情况。

首先,我有一个使用这种方法的 WCF RestFul 网络服务:

[WebInvoke(UriTemplate = "/Dynamic/*sParameter", Method = "POST", ResponseFormat = WebMessageFormat.Json)]
    public string ExecuteWebAPIRequest(string sParameter, Stream streamPost)
    
        ...

        var oClientFormatSinkProvider = new BinaryClientFormatterSinkProvider();
        IDictionary aoProps = new Hashtable();
        aoProps["port"] = 4626;
        aoProps["timeout"] = "-1";
        aoProps["name"] = "clientChan";
        TcpClientChannel channel = new TcpClientChannel(aoProps, oClientFormatSinkProvider);
        ChannelServices.RegisterChannel(channel, false);

        //-- Call Bridge
        string result = GetBridgeObject().ExecuteWebAPIRequest(sIpAddress, streamPost, sParameter);

        //-- Return result
        return result ?? "";
    

这是 GetBridgeObject() 方法的内容(即远程客户端):

private IBridge GetBridgeObject()
    
        return (IBridge)Activator.GetObject(typeof(IBridge), "tcp://localhost:4626/RemoteBridge");
    

接下来是包含此方法的桥接进程(即远程服务器):

public void StartService()
    
        //-- Initialize .NET remoting
        var oServerFormatSinkProvider = new BinaryServerFormatterSinkProvider();
        oServerFormatSinkProvider.TypeFilterLevel = TypeFilterLevel.Full;
        IDictionary aoProps = new Hashtable();
        aoProps["port"] = 4626;
        aoProps["timeout"] = "-1";
        aoProps["name"] = "serverChan";
        TcpServerChannel channel = new TcpServerChannel(aoProps, oServerFormatSinkProvider);
        ChannelServices.RegisterChannel(channel, false);
        RemotingConfiguration.RegisterWellKnownServiceType(typeof (Bridge), "RemoteBridge", WellKnownObjectMode.Singleton);
    

最后,在远程桥对象中,这个方法:

public string WUPP_ExecuteWebAPIRequestI(string sPPInstanceName, Stream oInputStream, string sParameter)
    
        ...

        int read = oInputStream.Read(buffer, 0, buffer.Length); //That's where the problem is
        ...    
    

正如代码 sn-p 中所述,当我尝试读取流时出现问题,我收到此错误:

异常:System.Runtime.Remoting.RemotingException:此远程代理没有通道接收器,这意味着服务器没有注册的服务器通道正在侦听,或者此应用程序没有合适的客户端通道与服务器通信。 在 System.Runtime.Remoting.Proxies.RemotingProxy.InternalInvoke(IMethodCallMessage reqMcmMsg,布尔值 useDispatchMessage,Int32 callType) 在 System.Runtime.Remoting.Proxies.RemotingProxy.Invoke(IMessage reqMsg) 在 System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData,Int32 类型) 在 System.IO.Stream.Read(Byte[] 缓冲区,Int32 偏移量,Int32 计数)

我确信我可以通过 .NET 远程处理传递流,因为在桥中,还有其他方法可以返回流并且效果很好。

注册频道时,我猜想问题出在远程服务器或客户端的某个地方,但经过两天的研究和测试,我仍然没有找到答案。

提前感谢您的帮助。

【问题讨论】:

【参考方案1】:

由于我遇到了类似的问题并且也需要解决方案,因此我终于找到了解决方案:需要以不同的方式注册客户端频道才能使其正常工作。

        // Creating a custom formatter for a TcpChannel sink chain.
        BinaryServerFormatterSinkProvider provider = new BinaryServerFormatterSinkProvider();
        BinaryClientFormatterSinkProvider clientProvider = new BinaryClientFormatterSinkProvider();
        provider.TypeFilterLevel = TypeFilterLevel.Full;

        Dictionary<string, object> dict = new Dictionary<string, object>();
        dict.Add("typeFilterLevel", "Full");
        dict.Add("port", "0");

        ChannelServices.RegisterChannel(new TcpChannel(dict, clientProvider, provider), false);

这里有趣的是

    通道是双向的 端口 0 告诉远程处理框架决定它应该使用哪个端口。 对于上传和下载流的类型FilterLevel Full 需要 设置。

有兴趣知道为什么我的答案在生产代码中有效,因此我的回答遭到了反对。

【讨论】:

以上是关于通过 .NET 远程处理将流传递给方法的主要内容,如果未能解决你的问题,请参考以下文章

通过 .NET 将参数传递给 XSLT 样式表

使用运算符将​​字符串流传递给 istream >>

将 lambda 作为 IL 流传递给辅助 AppDomain 并使用 DynamicMethod 将其组装回来

通过 .NET 远程传输后,双精度值发生了变化

通过进程间通信将停止参数从.NET应用程序传递给服务的最佳技术是啥?

如何将多个参数传递给 ASP.NET CORE MVC 中的 HttpGet 方法?