Question

I have a problem with .net remoting (and yes, it is my first attempt at using it, so I'm sorry if this is a stupid problem with an easy solution) and I've been searching for two days now and can't find any solution to my problem, so i apologize in advance if I've somehow missed the answer somewhere.

I'm building a server/client system using this code:

Server:

public Server() {
    DbConnector db = new DbConnector();

    BinaryServerFormatterSinkProvider provider = new BinaryServerFormatterSinkProvider();
    provider.TypeFilterLevel = TypeFilterLevel.Full;
    IDictionary props = new Hashtable();
    props["port"] = DbConnector.PORT;
    TcpChannel channel = new TcpChannel(props, null, provider);

    ChannelServices.RegisterChannel(channel, true);
    RemotingConfiguration.RegisterWellKnownServiceType(
       typeof(DbConnector), "test",
       WellKnownObjectMode.SingleCall);
}

Client:

public Form1() {
    InitializeComponent();

    BinaryServerFormatterSinkProvider provider = new BinaryServerFormatterSinkProvider();
    provider.TypeFilterLevel = TypeFilterLevel.Full;
    IDictionary props = new Hashtable();
    props["port"] = 0;
    props["ip"] = DbConnector.IP;
    TcpChannel channel = new TcpChannel(props, null, provider);

    ChannelServices.RegisterChannel(channel, true);
    db = (DbConnector)Activator.GetObject(typeof(DbConnector), "tcp://188.x.x.x/test");
    InitRest();
}

Whenever I try it locally (both with localhost but also with WAN IP) everything works fine, but as soon as I try it on separate machines, the client throws an exception.

{System.Net.Sockets.SocketException (0x80004005): A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond 192.168.0.100:9090

Server stack trace: 
   ved System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot, SocketAddress socketAddress)
   ved System.Net.Sockets.Socket.Connect(EndPoint remoteEP)
   ved System.Runtime.Remoting.Channels.RemoteConnection.CreateNewSocket(EndPoint ipEndPoint)
   ved System.Runtime.Remoting.Channels.RemoteConnection.CreateNewSocket()
   ved System.Runtime.Remoting.Channels.RemoteConnection.GetSocket()
   ved System.Runtime.Remoting.Channels.SocketCache.GetSocket(String machinePortAndSid, Boolean openNew)
   ved System.Runtime.Remoting.Channels.Tcp.TcpClientTransportSink.SendRequestWithRetry(IMessage msg, ITransportHeaders requestHeaders, Stream requestStream)
   ved System.Runtime.Remoting.Channels.Tcp.TcpClientTransportSink.ProcessMessage(IMessage msg, ITransportHeaders requestHeaders, Stream requestStream, ITransportHeaders& responseHeaders, Stream& responseStream)
   ved System.Runtime.Remoting.Channels.BinaryClientFormatterSink.SyncProcessMessage(IMessage msg)

Exception rethrown at [0]: 
   ved ECTunes.Database_Reader.Form1.InitRest() i d:\Dropbox\visual studio 2012\Projects\ECTunes\Database Communicator v0.2\Database Reader\Form1.cs:linje 69
   ved ECTunes.Database_Reader.Form1..ctor() i d:\Dropbox\visual studio 2012\Projects\ECTunes\Database Communicator v0.2\Database Reader\Form1.cs:linje 56
   ved ECTunes.Database_Reader.Program.Main() i d:\Dropbox\visual studio 2012\Projects\ECTunes\Database Communicator v0.2\Database Reader\Program.cs:linje 16
   ved System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
   ved System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
   ved Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
   ved System.Threading.ThreadHelper.ThreadStart_Context(Object state)
   ved System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   ved System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   ved System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   ved System.Threading.ThreadHelper.ThreadStart()}

I'm printing out come text whenever the constructor for the DbConnector is called and I can see that the client contacts the server, but I'm stuck at that.

After a bit more testing it seems that the problem is not with the connection itself but rather when I call a function that returns an object from the entity framework part of the system which is generated code. I've already modified the classes with [Serializable] and :MarshalByRefObject as shown:

//------------------------------------------------------------------------------
// <auto-generated>
//    This code was generated from a template.
//
//    Manual changes to this file may cause unexpected behavior in your application.
//    Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

namespace Database
{
    using System;
    using System.Collections.Generic;

    [Serializable]
    public partial class customer: MarshalByRefObject
    {
        public customer()
        {
            this.car = new HashSet<car>();
        }

        public int customerId { get; set; }
        public string name { get; set; }

        public virtual ICollection<car> car { get; set; }
    }
}

Yet when the client program calls a function that returns a 'customer' object and tries to access it the client throws the above exception.

My guess is that as the class is deriving from MarshalByRefObject it's the callback part that goes belly-up.

I've tried to use a specific port for the client channel as well, but to no avail.

I hope someone has a solution for this, in the end it's probably just me who's missing a key part.

Was it helpful?

Solution 2

I did solve it by making a wrapper class for the objects and use that for the transfer instead. A bit more work, but it works. Apparently you're not supposed to be able to send entity framework generated objects through these channels.

OTHER TIPS

I think I found it, thanks to you providing your sample!

ChannelServices.RegisterChannel(channel, true);

Set the ensureSecurity to false

ChannelServices.RegisterChannel(channel, false);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top