Remoting problems

G

Guest

Hi!

I have a config file that looks like this:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.runtime.remoting>
<application>
<service>
<wellknown mode="SingleCall" type="Interfaces, IMyFirstRemotableObj" objectUri="ControlCenter" />
</service>
<channels>
<channel ref="tcp" port="8086" />
</channels>
</application>
</system.runtime.remoting>
</configuration>

the server looks like this:
-----------------------------------------------
using Interfaces; //added in the referenses
using ClassLib.System; //added in the referenses
RemotingConfiguration.Configure(Environment.CurrentDirectory+"\\server.config");
lblServiceStatus.Text = "Service started";

the client:
-----------------------------------------------
using Interfaces; //added in the referenses
IMyFirstRemotableObj bol;
bol=(IMyFirstRemotableObj)Activator.GetObject(typeof(IMyFirstRemotableObj),@"tcp://192.168.2.24:8086/ControlCenter");
MessageBox.Show(bol.GetOSPlatform());

Interfaces:
-----------------------------------------------
using System;
namespace Interfaces
{
public interface IMyFirstRemotableObj
{
string GetOSPlatform();
}
}

ClassLib.System :
-----------------------------------------------
using System;
using Interfaces;
namespace ClassLib.System
{
[Serializable]
public class MyFirstRemotableObj : MarshalByRefObject, IMyFirstRemotableObj
{
public string GetOSPlatform()
{
return Environment.OSVersion.Version.ToString();
}
}
}


And the error:
-----------------------------------------------
System.IO.FileNotFoundException: File or assembly name IMyFirstRemotableObj, or one of its dependencies, was not found.
File name: "IMyFirstRemotableObj"

Server stack trace:
at System.Reflection.Assembly.nLoad(AssemblyName fileName, String codeBase, Boolean isStringized, Evidence assemblySecurity, Boolean throwOnFileNotFound, Assembly locationHint, StackCrawlMark& stackMark)
at System.Reflection.Assembly.InternalLoad(AssemblyName assemblyRef, Boolean stringized, Evidence assemblySecurity, StackCrawlMark& stackMark)
at System.Reflection.Assembly.InternalLoad(String assemblyString, Evidence assemblySecurity, StackCrawlMark& stackMark)
at System.Reflection.Assembly.Load(String assemblyString)
at System.Runtime.Remoting.RemotingConfigInfo.LoadType(String typeName, String assemblyName)
at System.Runtime.Remoting.RemotingConfigInfo.GetServerTypeForUri(String URI)
at System.Runtime.Remoting.RemotingConfigHandler.GetServerTypeForUri(String URI)
at System.Runtime.Remoting.RemotingServices.GetServerTypeForUri(String URI)
at System.Runtime.Remoting.Channels.BinaryServerFormatterSink.ProcessMessage(IServerChannelSinkStack sinkStack, IMessage requestMsg, ITransportHeaders requestHeaders, Stream requestStream, IMessage& responseMsg, ITransportHeaders& responseHeaders, Stream& responseStream)

Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at Interfaces.IMyFirstRemotableObj.GetOSPlatform()
at ControlCenter.ControlCenter.button1_Click(Object sender, EventArgs e)
at System.Windows.Forms.Control.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ButtonBase.WndProc(Message& m)
at System.Windows.Forms.Button.WndProc(Message& m)
at System.Windows.Forms.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)


If I use this code in the server:
TcpChannel chan = new TcpChannel(8086);
ChannelServices.RegisterChannel(chan);
RemotingConfiguration.RegisterWellKnownServiceType(typeof(MyFirstRemotableObj),"ControlCenter",WellKnownObjectMode.SingleCall);

Instead of
RemotingConfiguration.Configure(Environment.CurrentDirectory+"\\server.config");

then it will work fine, what's wrong?
 
S

Sunny

Hi,

Hi!

I have a config file that looks like this:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.runtime.remoting>
<application>
<service>
<wellknown mode="SingleCall" type="Interfaces, IMyFirstRemotableObj" objectUri="ControlCenter" />

<wellknown mode=... type="IMyFirstRemotableObj, Interfaces"....

from <wellknown> element docs:

<wellknown
type="ServerActivatedType, RemoteAssembly"
objectUri="ServerType.rem"
mode="Singleton"
/>

I.e. first goes the type, next the assembly.

Hope that helps
Cheers
Sunny
 
S

Sunny

Sorry,
a little mistake, the type exposed to remoting in <wellknown> should be
the type of your object, not the interface. The server needs to know
what kind of object instaniates. It can not instaniate an interface. So
your wellknow part shoud contain MyFirstRemotableObj, not IMyFirst...

Sunny
 
G

Guest

Yes I do!

In the applications directory I have these files:
server.config
Interfaces.dll
ClassLib.dll
ControlCenter.exe - the server/client
and 2 more DLL:s, not relevant to this problem.

The client and server is currently in the same exe-file but I'm running it on 2 different computers

I've also tried this:
<configuration>
<system.runtime.remoting>
<application>
<service>
<wellknown mode="SingleCall" type="ClassLib.System, MyFirstRemotableObj" objectUri="ControlCenter" />
</service>
<channels>
<channel ref="tcp" port="8086" />
<serverProviders>
<provider ref="wsdl" />
<formatter ref="soap" typeFilterLevel="Full" />
<formatter ref="binary" typeFilterLevel="Full" />
</serverProviders>
</channels>
</application>
</system.runtime.remoting>
</configuration>

This gives me the error:
System.IO.FileNotFoundException: File or assembly name MyFirstRemotableObj, or one of its dependencies, was not found.
File name: "MyFirstRemotableObj"

Regards
Anders Aleborg

Glyn said:
Have you got a copy of the interface assembly in the same directory as the client?

I must admit though, that if this is the problem it shouldn't work by NOT using a configuration file.

If I have time tonight I'll try it out and see what happens

Glyn Richards
MCSD .NET


Hi!

I have a config file that looks like this:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.runtime.remoting>
<application>
<service>
<wellknown mode="SingleCall" type="Interfaces, IMyFirstRemotableObj" objectUri="ControlCenter" />
</service>
<channels>
<channel ref="tcp" port="8086" />
</channels>
</application>
</system.runtime.remoting>
</configuration>

the server looks like this:
-----------------------------------------------
using Interfaces; //added in the referenses
using ClassLib.System; //added in the referenses
RemotingConfiguration.Configure(Environment.CurrentDirectory+"\\server.config");
lblServiceStatus.Text = "Service started";

the client:
-----------------------------------------------
using Interfaces; //added in the referenses
IMyFirstRemotableObj bol;
bol=(IMyFirstRemotableObj)Activator.GetObject(typeof(IMyFirstRemotableObj),@"tcp://192.168.2.24:8086/ControlCenter");
MessageBox.Show(bol.GetOSPlatform());

Interfaces:
-----------------------------------------------
using System;
namespace Interfaces
{
public interface IMyFirstRemotableObj
{
string GetOSPlatform();
}
}

ClassLib.System :
-----------------------------------------------
using System;
using Interfaces;
namespace ClassLib.System
{
[Serializable]
public class MyFirstRemotableObj : MarshalByRefObject, IMyFirstRemotableObj
{
public string GetOSPlatform()
{
return Environment.OSVersion.Version.ToString();
}
}
}


And the error:
-----------------------------------------------
System.IO.FileNotFoundException: File or assembly name IMyFirstRemotableObj, or one of its dependencies, was not found.
File name: "IMyFirstRemotableObj"

Server stack trace:
at System.Reflection.Assembly.nLoad(AssemblyName fileName, String codeBase, Boolean isStringized, Evidence assemblySecurity, Boolean throwOnFileNotFound, Assembly locationHint, StackCrawlMark& stackMark)
at System.Reflection.Assembly.InternalLoad(AssemblyName assemblyRef, Boolean stringized, Evidence assemblySecurity, StackCrawlMark& stackMark)
at System.Reflection.Assembly.InternalLoad(String assemblyString, Evidence assemblySecurity, StackCrawlMark& stackMark)
at System.Reflection.Assembly.Load(String assemblyString)
at System.Runtime.Remoting.RemotingConfigInfo.LoadType(String typeName, String assemblyName)
at System.Runtime.Remoting.RemotingConfigInfo.GetServerTypeForUri(String URI)
at System.Runtime.Remoting.RemotingConfigHandler.GetServerTypeForUri(String URI)
at System.Runtime.Remoting.RemotingServices.GetServerTypeForUri(String URI)
at System.Runtime.Remoting.Channels.BinaryServerFormatterSink.ProcessMessage(IServerChannelSinkStack sinkStack, IMessage requestMsg, ITransportHeaders requestHeaders, Stream requestStream, IMessage& responseMsg, ITransportHeaders& responseHeaders, Stream& responseStream)

Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at Interfaces.IMyFirstRemotableObj.GetOSPlatform()
at ControlCenter.ControlCenter.button1_Click(Object sender, EventArgs e)
at System.Windows.Forms.Control.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ButtonBase.WndProc(Message& m)
at System.Windows.Forms.Button.WndProc(Message& m)
at System.Windows.Forms.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)


If I use this code in the server:
TcpChannel chan = new TcpChannel(8086);
ChannelServices.RegisterChannel(chan);
RemotingConfiguration.RegisterWellKnownServiceType(typeof(MyFirstRemotableObj),"ControlCenter",WellKnownObjectMode.SingleCall);

Instead of
RemotingConfiguration.Configure(Environment.CurrentDirectory+"\\server.config");

then it will work fine, what's wrong?
 
G

Guest

please se my reply to Glyn

Sunny said:
Sorry,
a little mistake, the type exposed to remoting in <wellknown> should be
the type of your object, not the interface. The server needs to know
what kind of object instaniates. It can not instaniate an interface. So
your wellknow part shoud contain MyFirstRemotableObj, not IMyFirst...

Sunny
 
S

Sunny

Hi,
in my first post I have wrote that yout "type" element of the
<wellknown> tag is wrong. The class name should be placed before the
assembly name, not the way you use it.

Sunny
 
S

Sunny

Hi,
try:

type="ClassLib.System.MyFirstRemotableObj, ClassLib"


if it fails, please post a copy of the exception.

Also, there is no way using all these lines to produce exactly the same
error. In the error message it says which class/file it can not find. As
the combinations are different, there should be different errors.

Sunny
 
S

Sunny

Hi,

Great, that did the trick :D Thanks!!!
Next question, I tried this:
<service>
<wellknown mode="SingleCall" type="ClassLib.System.MyFirstRemotableObj, ClassLib" objectUri="ControlCenter" />
<wellknown mode="SingleCall" type="ClassLib.System.MySecondRemotableObj, ClassLib" objectUri="ControlCenter" />
</service>

You are trying to expose 2 different objects on the same uri. This is
not possible. You should select different uris.
The project I'm working with contains a great number of classes in different folders,
ClassLib.System
ClassLib.IIS
ClassLib.Common
etc...
And we need to be able to talk to all classes through remoting, how can that be done?

As I said, expose them with different uris.
And the last question, security, how can we make the remoting secure?
Only our developed applications should be able to talk with the remoting server and the traffic should be encrypted. Everything will be behind firewalls but we wan't to be shure... How can we solve it? From what I've heard TCP and binary is the best format to use, correct?

There were some discussions in the newsgroups, that it is nearly
impossible to implement application signature type of security. As far
as your application can be disassembled not with big efforts, any
implementation you put in there to identify the application, can easily
be duplicated. There is no build-in mechanism, so you have to implement
something by yourself. But I can not get the point, if you are behind
firewalls, and the use will be only internal, how can any external
application try to connect to your server classes?
One way or another, such an application identification should be
implemented. You can use custom channel syncs to to add some
identification to every remoting call.

If you need user authentication, you can go with IIS hosted remoting
objects, and use IIS's security.

The same applies to the encryption as well - you may use IIS as host and
use it's SSL capabilities.

The problem is that with IIS hosted objects you have to use HTTP
channel. But still you can use binary formatter. HTTP is a little bit
slower than TCP, and adding encryption will slow down the thinks more.

Most probably you should rethink your architecture, etc.

You may take a look at third party solutions like genuine channels. They
have encrypted TCP channels, and are not expensive.

Cheers
Sunny
 
G

Guest

Thanks :)

Sunny said:
Hi,



You are trying to expose 2 different objects on the same uri. This is
not possible. You should select different uris.


As I said, expose them with different uris.


There were some discussions in the newsgroups, that it is nearly
impossible to implement application signature type of security. As far
as your application can be disassembled not with big efforts, any
implementation you put in there to identify the application, can easily
be duplicated. There is no build-in mechanism, so you have to implement
something by yourself. But I can not get the point, if you are behind
firewalls, and the use will be only internal, how can any external
application try to connect to your server classes?
One way or another, such an application identification should be
implemented. You can use custom channel syncs to to add some
identification to every remoting call.

If you need user authentication, you can go with IIS hosted remoting
objects, and use IIS's security.

The same applies to the encryption as well - you may use IIS as host and
use it's SSL capabilities.

The problem is that with IIS hosted objects you have to use HTTP
channel. But still you can use binary formatter. HTTP is a little bit
slower than TCP, and adding encryption will slow down the thinks more.

Most probably you should rethink your architecture, etc.

You may take a look at third party solutions like genuine channels. They
have encrypted TCP channels, and are not expensive.

Cheers
Sunny
 
G

Guest

Got a new problem, I get this error:
System.Runtime.Remoting.RemotingException: Det gick inte att hitta begärd tjänst

Server stack trace:
at System.Runtime.Remoting.Channels.BinaryServerFormatterSink.ProcessMessage(IServerChannelSinkStack sinkStack, IMessage requestMsg, ITransportHeaders requestHeaders, Stream requestStream, IMessage& responseMsg, ITransportHeaders& responseHeaders, Stream& responseStream)

Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at Interfaces.IMerak.set_DomainName(String value)
at ControlCenter.ControlCenter.button2_Click(Object sender, EventArgs e) in d:\c#\webcresiterweb\controlcenter\controlcenter.cs:line 248

The code I'm using works fine If I run it without remoting:
IMerak mail;
mail=(IMerak)Activator.GetObject(typeof(IMerak),@"tcp://localhost:8086/Merak");
mail.DomainName = "test.se"; //complains on this line...
mail.Domain_Accounts = 25;
mail.Domain_Description = "test";
mail.Domain_DiskQuota = 1024;
MessageBox.Show(mail.CreateDomain().ToString());

the interface looks like this:
public interface IMerak
{
string DomainName
{
set;
}
bool GetUser();
DataSet GetAllUsers();
bool GetUnknownUsers();
bool GetDomain();
int Domain_Accounts
{
get;
set;
}
int Domain_DiskQuota
{
get;
set;
}
string Domain_Description
{
get;
set;
}
string Domain_Type
{
get;
set;
}
string Domain_Value
{
get;
set;
}
string Domain_UnknownUsers
{
get;
set;
}
string Domain_UnknownUsersForward
{
get;
set;
}
bool CreateDomain();
bool CreateUser();
bool DeleteDomain();
bool DeleteUser();
bool UpdateUnknownUsers();
bool UpdateUser();
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top