简体   繁体   中英

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 :

[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):

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. 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)

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.

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.
  3. for up- and download of streams the typeFilterLevel Full needs to be set.

Would be interested to know why my answer got a downvote as the solution works in production code.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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