Remoting beginner: Whats missing in this code?

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

Yesterday I got the idea to use remoting for the test interface between our
Windows Xp Embedded - based device and our system test application.
I started looking in the MSDN help and made the code below.
My server class (RemotingServer) is located in one assembly (LibS.dll) used
by the device software and the test system will use another assembly
(LibC.dll) including my client class (TestConnectionRemoting).

We have NO security issues - the interface should be open for any
application using LibS.dll (or any other for that matter).

My immediate problem is that I get a SerilizationException when invoking a
method (the SetEventOutputInterface method call) on the remote object:
"Because of security restrictions, the type System.Runtime.Remoting.ObjRef
cannot be accessed."
- InnerException is SecurityException: "Request failed."


The next question:
I'm passing interface references to the server where one of them will be
saved in the server and used asynchronuosly later. Will I have to do any
preparation for that to work? - and can I do that?

Any help is much appreciated because remoting is not a focus area in this
project so I just have to make this test interface work so I can continue
with my other tasks. Though it is very interesting.....

Here's my code:

--------------- THE CLIENT ( LibC.dll) ---------------

class TestConnectionRemoting : MarshalByRefObject, ITestOutput, IEventOutput
{
AccessorBase m_Accessor = null;

public override bool Connect()
{
WellKnownClientTypeEntry typeentry =
new WellKnownClientTypeEntry( typeof( AccessorBase ),
"tcp://localhost:399/testinterface" );
typeentry.ApplicationUrl = "tcp://localhost:399/testinterface";
RemotingConfiguration.RegisterWellKnownClientType( typeentry );

m_Accessor = new AccessorBase();
// deliver event-output interface reference
m_Accessor.SetEventOutputInterface( (IEventOutput) this );
// call remote method where output will be sent back through the
ITestOutput interface.
m_Accessor.ExecuteCommand( (ITestOutput) this, "login developer" );

return true;
}
 
Jan said:
Yesterday I got the idea to use remoting for the test interface between our
Windows Xp Embedded - based device and our system test application.
I started looking in the MSDN help and made the code below.
My server class (RemotingServer) is located in one assembly (LibS.dll) used
by the device software and the test system will use another assembly
(LibC.dll) including my client class (TestConnectionRemoting).

We have NO security issues - the interface should be open for any
application using LibS.dll (or any other for that matter).

My immediate problem is that I get a SerilizationException when invoking a
method (the SetEventOutputInterface method call) on the remote object:
"Because of security restrictions, the type System.Runtime.Remoting.ObjRef
cannot be accessed."
- InnerException is SecurityException: "Request failed."

In .NET by default marshaling is available only for a primitive types
You have to set Type Filtering to Full or implement ISerializable or ...
How to do this;)
It's simple just read
http://msdn.microsoft.com/library/d...pconautomaticdeserializationinnetremoting.asp
 
Thanks alot, Lukasz. That was the clear answer to my first question. It works
perfectly. Cheers.

- but then...

I now get a RemotingException when using a passed interface in the server:
"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."

Can anybody help me on this one also?


---------------------------------------------------
FYI: My server now looks like this:


public class RemotingServer
{
private static TcpChannel m_Channel = null;
private static AccessorBase m_TestRoot = null;

public static void StartTcpAccess( int port, AccessorBase root )
{
if ( m_Channel != null )
throw new Exception( "A listener has already been started." );

BinaryServerFormatterSinkProvider provider = new
BinaryServerFormatterSinkProvider();
provider.TypeFilterLevel = TypeFilterLevel.Full;

// Creating the IDictionary to set the port on the channel instance.
IDictionary props = new Hashtable();
props["port"] = port;

m_Channel = new TcpChannel( props, null, provider );
ChannelServices.RegisterChannel( m_Channel, false );

RemotingServices.Marshal( root, "testinterface", typeof(AccessorBase) );

m_TestRoot = root;
}
}
 
Jan said:
Thanks alot, Lukasz. That was the clear answer to my first question. It works
perfectly. Cheers.

- but then...

I now get a RemotingException when using a passed interface in the server:
"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."

Can anybody help me on this one also?
Sorry , for partial responses but i had to think about it i was working
with remoting some times ago:)
I think you have to register channel on client side too
for example like this
ChannelServices.RegisterChannel(new TcpChannel());
 
Thanks again, Lukasz.

I now have it up and running.

Best regards,
Jan


FYI: The client code now looks like this:


class TestConnectionRemoting : MarshalByRefObject, ITestOutput, IEventOutput
{
AccessorBase m_Accessor = null;

public override bool Connect()
{
WellKnownClientTypeEntry typeentry =
new WellKnownClientTypeEntry( typeof( AccessorBase ),
"tcp://localhost:399/testinterface" );
typeentry.ApplicationUrl = "tcp://localhost:399/testinterface";
RemotingConfiguration.RegisterWellKnownClientType( typeentry );

BinaryClientFormatterSinkProvider sinkprovider = new
BinaryClientFormatterSinkProvider();
IDictionary properties = new Hashtable();
properties["name"] = "TcpBinary";
properties["port"] = 0;
BinaryServerFormatterSinkProvider provider = new
BinaryServerFormatterSinkProvider();
provider.TypeFilterLevel = TypeFilterLevel.Full;

ChannelServices.RegisterChannel( new TcpChannel( properties,
sinkprovider, provider ), false );

m_Accessor = new AccessorBase();
// deliver event-output interface reference
m_Accessor.SetEventOutputInterface( (IEventOutput) this );
// call remote method where output will be sent back through the
ITestOutput interface.
m_Accessor.ExecuteCommand( (ITestOutput) this, "login developer" );

return true;
}
 
Back
Top