简体   繁体   English

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

[英]Passing a stream to a method via .NET remoting

Let me briefly describe the situation. 让我简要描述一下情况。

First, I have a WCF RestFul webservice with this method : 首先,我有一个使用此方法的WCF RestFul Web服务:

[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 ?? "";
    }

here is the content of the GetBridgeObject() method (that would be the remoting client): 这是GetBridgeObject()方法的内容(将是远程客户端):

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

Next, there is the bridge process containing this method (that would be the remoting server): 接下来,有一个包含此方法的桥接进程(将是远程服务器):

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

And finaly, in the remote bridge object, this method : 最后,在远程网桥对象中,此方法:

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

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

As stated in the code snippet, the problem occurs when I try to read the stream, i get this error : 如代码片段中所述,当我尝试读取流时,出现此问题:

Exception: System.Runtime.Remoting.RemotingException: This remoting proxy has no channel sink which means either the server has no registered server channels that are listening, or this application has no suitable client channel to talk to the server. 异常:System.Runtime.Remoting.RemotingException:此远程代理没有通道接收器,这意味着服务器没有正在侦听的注册服务器通道,或者此应用程序没有合适的客户端通道可以与服务器通信。 at System.Runtime.Remoting.Proxies.RemotingProxy.InternalInvoke(IMethodCallMessage reqMcmMsg, Boolean useDispatchMessage, Int32 callType) at System.Runtime.Remoting.Proxies.RemotingProxy.Invoke(IMessage reqMsg) at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type) at System.IO.Stream.Read(Byte[] buffer, Int32 offset, Int32 count) 在System.Runtime.Remoting.Proxies.RemotingProxy.Invoke(IMessage reqMsg)在System.Runtime.Remoting.Proxies。 (MessageData&msgData,Int32类型)位于System.IO.Stream.Read(字节[]缓冲区,Int32偏移量,Int32计数)

I know for sure I can pass streams via .NET remoting because in the bridge, there are other methods that return streams and that work well. 我知道我可以通过.NET远程传递流,因为在网桥中,还有其他方法可以返回流并且可以很好地工作。

I guess the problem is somewhere in the remoting server or client when I register the channels but after two days of research and tests, i still haven't found an answer. 我想问题出在注册频道时是在远程服务器或客户端中的某个地方,但是经过两天的研究和测试,我仍然没有找到答案。

Thanks in advance for your help. 在此先感谢您的帮助。

Since I had a similar problem and needed a solution as well, I finally found a solution: the client channel needs to be registered differently to make it work. 由于我遇到了类似的问题,并且也需要解决方案,因此我终于找到了解决方案:需要对客户端通道进行不同的注册才能使其正常工作。

        // 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);

The interessting things here are 有趣的是

  1. the channel is bidirectional 通道是双向的
  2. port 0 tells remoting framework to decide which port it should use. 端口0告诉远程处理框架决定应使用哪个端口。
  3. for up- and download of streams the typeFilterLevel Full needs to be set. 要上传和下载流,需要设置typeFilterLevel Full。

Would be interested to know why my answer got a downvote as the solution works in production code. 感兴趣的是,为什么该解决方案可以在生产代码中使用,所以我的答案为什么会被否决。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM