HighTechTalks DotNet Forums  

Problems with Remote Events using .NET 2.0

Dotnet Framework (Remoting) microsoft.public.dotnet.framework.remoting


Discuss Problems with Remote Events using .NET 2.0 in the Dotnet Framework (Remoting) forum.



Reply
 
Thread Tools Search this Thread Display Modes
  #1  
Old   
Steve
 
Posts: n/a

Default Problems with Remote Events using .NET 2.0 - 12-05-2007 , 04:52 AM






Hi guys,

I'm having a problem with remote events in .NET 2.0. I've written a
really simple test application (taken from the Microsoft book
"Microsoft .NET Distributed Applications: Integrating XML Web Services
and .NET Remoting"). The aim is for the client to receive an event
raised by an object on the server as a result of an asynchronous call
from the client.

The server (a console application) comprises a config file:

=============================================
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.runtime.remoting>
<application name="Server">
<service>
<activated type="DLL.RemoteObject, DLL"/>
</service>
<channels>
<channel ref="tcp server" port="8080" />
</channels>
</application>
</system.runtime.remoting>
</configuration>
=============================================

....and Program.cs with a Main method:

=============================================
public static void Main(string[] args)
{
Console.WriteLine("Attempting to start server...");

try
{
//Start listening to the remoting channel:
RemotingConfiguration.Configure("Server.exe.config ",
false);

Console.WriteLine("Server is now listening");
}
catch(Exception e)
{
Console.WriteLine("Error: {0}", e.Message);
}

Console.WriteLine("Press Return to quit...");
Console.ReadLine();
}
=============================================

A separate DLL contains a remote object (RemoteObject.cs):

=============================================
public class RemoteObject : MarshalByRefObject
{
public event EventHandler<TaskCompleteEventArgs> TaskComplete;

public void GetActiveDomainAsychronous()
{
new Thread
(
delegate()
{
Console.WriteLine("Getting active domain...");
Thread.Sleep(3000);
string activeDomain =
AppDomain.CurrentDomain.FriendlyName;
Console.WriteLine("Active domain obtained");
OnTaskComplete(new
TaskCompleteEventArgs(activeDomain));
}
).Start();
}

protected void OnTaskComplete(TaskCompleteEventArgs e)
{
if (TaskComplete != null)
{
foreach (Delegate d in
TaskComplete.GetInvocationList())
{
try
{
((EventHandler<TaskCompleteEventArgs>)d)(this,
e);
}
catch
{
//Ignore
}
}
}
}
}
=============================================

....an event args class:

=============================================
[Serializable]
public class TaskCompleteEventArgs : EventArgs
{
private readonly string activeDomain;

public TaskCompleteEventArgs(string activeDomain)
{
this.activeDomain = activeDomain;
}

public string ActiveDomain
{
get
{
return activeDomain;
}
}
}
=============================================

....and a listener class:

=============================================
[Serializable]
public class EventListener : MarshalByRefObject
{
public void TaskComplete(object sender, TaskCompleteEventArgs
e)
{
Console.WriteLine("Asynchronous response received. Domain:
{0}", e.ActiveDomain);
}

public override object InitializeLifetimeService()
{
return null;
}
}
=============================================

The client (another console application) also comprises a config file:

=============================================
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.runtime.remoting>
<application name="Client">
<client url="tcp://localhost:8080/Server">
<activated type="DLL.RemoteObject, DLL"/>
</client>
<channels>
<channel ref="tcp client" />
</channels>
</application>
</system.runtime.remoting>
</configuration>
=============================================

....and a Program.cs:

=============================================
public class Program
{
private static EventListener listener = new EventListener();

public static void Main(string[] args)
{
string currentDomain =
AppDomain.CurrentDomain.FriendlyName;

Console.WriteLine("Client application domain: {0}",
currentDomain);
Console.WriteLine("Attempting to start client...");

try
{
//Start listening to the remoting channel:
RemotingConfiguration.Configure("Client.exe.config ",
false);

Console.WriteLine("Client is now running");

Console.WriteLine("Construct a remote object...");
RemoteObject remoteObject = new RemoteObject();

remoteObject.TaskComplete += listener.TaskComplete;

Console.WriteLine("Perform asynchronous request...");
remoteObject.GetActiveDomainAsychronous();
}
catch (Exception e)
{
Console.WriteLine("Error: {0}", e.Message);
}

Console.WriteLine("Press Return to quit...");
Console.ReadLine();
}
}
}
=============================================

The server starts with no problems, but when the client starts, I get
a problem when it hits the line 'remoteObject.TaskComplete +=
listener.TaskComplete;'. The error is:

"Type System.DelegateSerializationHolder and the types derived from it
(such as System.DelegateSerializationHolder) are not permitted to be
deserialized at this security level."

I'm having problems getting to the bottom of the problem. Any ideas?

Thanks in advance guys,

Steve.

Reply With Quote
  #2  
Old   
jacky kwok
 
Posts: n/a

Default Re: Problems with Remote Events using .NET 2.0 - 12-05-2007 , 09:19 PM






Steve wrote:
Quote:
Hi guys,

I'm having a problem with remote events in .NET 2.0. I've written a
really simple test application (taken from the Microsoft book
"Microsoft .NET Distributed Applications: Integrating XML Web Services
and .NET Remoting"). The aim is for the client to receive an event
raised by an object on the server as a result of an asynchronous call
from the client.

The server (a console application) comprises a config file:

=============================================
?xml version="1.0" encoding="utf-8" ?
configuration
system.runtime.remoting
application name="Server"
service
activated type="DLL.RemoteObject, DLL"/
/service
channels
channel ref="tcp server" port="8080" /
/channels
/application
/system.runtime.remoting
/configuration
=============================================

...and Program.cs with a Main method:

=============================================
public static void Main(string[] args)
{
Console.WriteLine("Attempting to start server...");

try
{
//Start listening to the remoting channel:
RemotingConfiguration.Configure("Server.exe.config ",
false);

Console.WriteLine("Server is now listening");
}
catch(Exception e)
{
Console.WriteLine("Error: {0}", e.Message);
}

Console.WriteLine("Press Return to quit...");
Console.ReadLine();
}
=============================================

A separate DLL contains a remote object (RemoteObject.cs):

=============================================
public class RemoteObject : MarshalByRefObject
{
public event EventHandler<TaskCompleteEventArgs> TaskComplete;

public void GetActiveDomainAsychronous()
{
new Thread
(
delegate()
{
Console.WriteLine("Getting active domain...");
Thread.Sleep(3000);
string activeDomain =
AppDomain.CurrentDomain.FriendlyName;
Console.WriteLine("Active domain obtained");
OnTaskComplete(new
TaskCompleteEventArgs(activeDomain));
}
).Start();
}

protected void OnTaskComplete(TaskCompleteEventArgs e)
{
if (TaskComplete != null)
{
foreach (Delegate d in
TaskComplete.GetInvocationList())
{
try
{
((EventHandler<TaskCompleteEventArgs>)d)(this,
e);
}
catch
{
//Ignore
}
}
}
}
}
=============================================

...an event args class:

=============================================
[Serializable]
public class TaskCompleteEventArgs : EventArgs
{
private readonly string activeDomain;

public TaskCompleteEventArgs(string activeDomain)
{
this.activeDomain = activeDomain;
}

public string ActiveDomain
{
get
{
return activeDomain;
}
}
}
=============================================

...and a listener class:

=============================================
[Serializable]
public class EventListener : MarshalByRefObject
{
public void TaskComplete(object sender, TaskCompleteEventArgs
e)
{
Console.WriteLine("Asynchronous response received. Domain:
{0}", e.ActiveDomain);
}

public override object InitializeLifetimeService()
{
return null;
}
}
=============================================

The client (another console application) also comprises a config file:

=============================================
?xml version="1.0" encoding="utf-8" ?
configuration
system.runtime.remoting
application name="Client"
client url="tcp://localhost:8080/Server"
activated type="DLL.RemoteObject, DLL"/
/client
channels
channel ref="tcp client" /
/channels
/application
/system.runtime.remoting
/configuration
=============================================

...and a Program.cs:

=============================================
public class Program
{
private static EventListener listener = new EventListener();

public static void Main(string[] args)
{
string currentDomain =
AppDomain.CurrentDomain.FriendlyName;

Console.WriteLine("Client application domain: {0}",
currentDomain);
Console.WriteLine("Attempting to start client...");

try
{
//Start listening to the remoting channel:
RemotingConfiguration.Configure("Client.exe.config ",
false);

Console.WriteLine("Client is now running");

Console.WriteLine("Construct a remote object...");
RemoteObject remoteObject = new RemoteObject();

remoteObject.TaskComplete += listener.TaskComplete;

Console.WriteLine("Perform asynchronous request...");
remoteObject.GetActiveDomainAsychronous();
}
catch (Exception e)
{
Console.WriteLine("Error: {0}", e.Message);
}

Console.WriteLine("Press Return to quit...");
Console.ReadLine();
}
}
}
=============================================

The server starts with no problems, but when the client starts, I get
a problem when it hits the line 'remoteObject.TaskComplete +=
listener.TaskComplete;'. The error is:

"Type System.DelegateSerializationHolder and the types derived from it
(such as System.DelegateSerializationHolder) are not permitted to be
deserialized at this security level."

I'm having problems getting to the bottom of the problem. Any ideas?

Thanks in advance guys,

Steve.

In server side, need to set the "typeFilterLevel=Full" in the server
channel, the following code is for TCPchannel.

Search "typeFilterLevel","Full","Event" in google can find many information.



IDictionary providerProps = new Hashtable();
providerProps["typeFilterLevel"] = "Full";
BinaryServerFormatterSinkProvider provider = new
BinaryServerFormatterSinkProvider(providerProps,nu ll);
IDictionary props = new Hashtable();
props["port"] = 59961;

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



--
Jacky Kwok
jacky@alumni_DOT_cuhk_DOT_edu_DOT_hk


Reply With Quote
  #3  
Old   
Steve
 
Posts: n/a

Default Re: Problems with Remote Events using .NET 2.0 - 12-06-2007 , 08:00 AM



Hi Jacky!

Thanks very much for your help. I've managed to make some progress.
I've changed the config files as follows:

Server config file:
=============================
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.runtime.remoting>
<application name="Server">
<service>
<activated type="DLL.RemoteObject, DLL"/>
</service>
<channels>
<channel ref="tcp server" port="8080">
<serverProviders>
<provider ref="wsdl" />
<formatter ref="soap" typeFilterLevel="Full" />
<formatter ref="binary" typeFilterLevel="Full" />
</serverProviders>
</channel>
</channels>
</application>
</system.runtime.remoting>
</configuration>
=============================

Client config file:
=============================
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.runtime.remoting>
<application name="Client">
<client url="tcp://localhost:8080/Server">
<activated type="DLL.RemoteObject, DLL"/>
</client>
<channels>
<channel ref="tcp client" port="0">
<serverProviders>
<formatter ref="soap" typeFilterLevel="Full" />
<formatter ref="binary" typeFilterLevel="Full" />
</serverProviders>
</channel>
</channels>
</application>
</system.runtime.remoting>
</configuration>
=============================

This gets me a bit further. Now, when the server hits the line of code
'((EventHandler<TaskCompleteEventArgs>)d)(this, e);' in the
OnTaskComplete method of the RemoteObject class, I get the following
error:

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

I guess I'm still missing something from the configuration files?!

Many thanks,

Steve.





Reply With Quote
  #4  
Old   
jacky kwok
 
Posts: n/a

Default Re: Problems with Remote Events using .NET 2.0 - 12-06-2007 , 08:58 PM



Steve wrote:
Quote:
Hi Jacky!

Thanks very much for your help. I've managed to make some progress.
I've changed the config files as follows:

Server config file:
=============================
?xml version="1.0" encoding="utf-8" ?
configuration
system.runtime.remoting
application name="Server"
service
activated type="DLL.RemoteObject, DLL"/
/service
channels
channel ref="tcp server" port="8080"
serverProviders
provider ref="wsdl" /
formatter ref="soap" typeFilterLevel="Full" /
formatter ref="binary" typeFilterLevel="Full" /
/serverProviders
/channel
/channels
/application
/system.runtime.remoting
/configuration
=============================

Client config file:
=============================
?xml version="1.0" encoding="utf-8" ?
configuration
system.runtime.remoting
application name="Client"
client url="tcp://localhost:8080/Server"
activated type="DLL.RemoteObject, DLL"/
/client
channels
channel ref="tcp client" port="0"
serverProviders
formatter ref="soap" typeFilterLevel="Full" /
formatter ref="binary" typeFilterLevel="Full" /
/serverProviders
/channel
/channels
/application
/system.runtime.remoting
/configuration
=============================

This gets me a bit further. Now, when the server hits the line of code
'((EventHandler<TaskCompleteEventArgs>)d)(this, e);' in the
OnTaskComplete method of the RemoteObject class, I get the following
error:

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

I guess I'm still missing something from the configuration files?!

Many thanks,

Steve.




Do not exactly sure what is your problem. It seems it is the client side
server channel is not ready.
Since I always use code to build the remote function (since my app
always needs to allow user can configure the setting in UI). I do not
familiar to use the config file setting.

in my client app which needs to receive remote event, the code to build
the remote channal is

================================================== ===
channel=null;
int port=8000;
try
{
channel=new TcpChannel(port);
}
catch //(Exception ex)
{
MessageBox.Show(this,"Cannot create remote channel in port
8000!\nRemote function is not ready!",
"Error");
return;
}

try
{
ChannelServices.RegisterChannel(channel);
}
catch(Exception)
{
MessageBox.Show(this,"Cannot create remote channel in port
8000!\nRemote function is not ready!",
"Error");
channel=null;
}
=================================================

I think you can try not use the port "0" in client side.

--
Jacky Kwok
jacky@alumni_DOT_cuhk_DOT_edu_DOT_hk


Reply With Quote
  #5  
Old   
Steve
 
Posts: n/a

Default Re: Problems with Remote Events using .NET 2.0 - 12-10-2007 , 09:53 AM



Hi Jacky,

I tried changing the client port to 8000, but got the same error. 0
should be fine, since it just tells the client to communicate via any
available port, which it will decide upon automatically.

Does anyone know what the correct contents of each configuration file
should be?

Many thanks,

Steve.

Reply With Quote
  #6  
Old   
jacky kwok
 
Posts: n/a

Default Re: Problems with Remote Events using .NET 2.0 - 12-10-2007 , 10:52 PM



Steve wrote:
Quote:
Hi Jacky,

I tried changing the client port to 8000, but got the same error. 0
should be fine, since it just tells the client to communicate via any
available port, which it will decide upon automatically.

Does anyone know what the correct contents of each configuration file
should be?

Many thanks,

Steve.
try simplify the client config, in my testing, the following config work
well in simple remote event testing.

client config
=================
<configuration>
<system.runtime.remoting>
<application>
<client>
<wellknown
type="RemoteEvent.RemoteObject, RemoteEvent"
url="tcp://localhost:18806/object1uri"
/>
</client>
<channels>
<channel
ref="tcp"
port="0"
/>
</channels>
</application>
</system.runtime.remoting>
</configuration>
=================

server config
===============
<configuration>
<system.runtime.remoting>
<application>
<service>
<wellknown
mode="Singleton"
type="RemoteEvent.RemoteObject, RemoteEvent"
objectUri="object1uri"
/>
</service>
<channels>
<channel
ref="tcp"
port="18806"
Quote:
serverProviders
<formatter ref="binary" typeFilterLevel="Full" />
</serverProviders>
</channel>
</channels>
</application>
</system.runtime.remoting>
</configuration>
===============================

--
Jacky Kwok
jacky@alumni_DOT_cuhk_DOT_edu_DOT_hk


Reply With Quote
  #7  
Old   
Steve
 
Posts: n/a

Default Re: Problems with Remote Events using .NET 2.0 - 12-12-2007 , 12:00 PM



Hi Jacky,

I'm still having problems! Mind if I send you my code so you can try
and repro the problem?

Thanks,

Steve.

Reply With Quote
  #8  
Old   
Steve
 
Posts: n/a

Default Re: Problems with Remote Events using .NET 2.0 - 12-12-2007 , 01:33 PM



Ah, it turns out the problem was thanks to my local firewall. With a
few further tweaks, I've managed to get the thing working. In case
anyone else is following this thread, here is the complete code
listing to get the thing working (this example shows events and
delegates being used for callbacks).

Thanks to everyone for their help!

================================
Server
================================
Server Config:
================================
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.runtime.remoting>
<application name="Server">
<service>
<activated type="DLL.RemoteObject, DLL"/>
</service>
<channels>
<channel ref="tcp" port="8000" >
<serverProviders>
<formatter ref="binary" typeFilterLevel="Full" />
</serverProviders>
</channel>
</channels>
</application>
</system.runtime.remoting>
</configuration>
================================
Server Program:
================================
using System;
using System.Collections.Generic;
using System.Runtime.Remoting;
using System.Text;

namespace Server
{
public static class Program
{
public static void Main(string[] args)
{
Console.WriteLine("Attempting to start server...");

try
{
//Start listening to the remoting channel:
RemotingConfiguration.Configure("Server.exe.config ",
false);

Console.WriteLine("Server is now listening");
}
catch(Exception e)
{
Console.WriteLine("Error: {0}", e.Message);
}

Console.WriteLine("Press Return to quit...");
Console.ReadLine();
}
}
}
================================

================================
Client
================================
Client Config:
================================
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.runtime.remoting>
<application name="Client">
<client url="tcp://localhost:8000/Server">
<activated type="DLL.RemoteObject, DLL"/>
</client>
<channels>
<channel ref="tcp" port="0" >
<serverProviders>
<formatter ref="binary" typeFilterLevel="Full" />
</serverProviders>
</channel>
</channels>
</application>
</system.runtime.remoting>
</configuration>
================================
Client Program:
================================
using System;
using System.Collections.Generic;
using System.Runtime.Remoting;
using System.Text;
using DLL;

namespace Client
{
public class Program
{
private static EventListener listener = new EventListener();

public static void Main(string[] args)
{
string currentDomain =
AppDomain.CurrentDomain.FriendlyName;

Console.WriteLine("Client application domain: {0}",
currentDomain);
Console.WriteLine("Attempting to start client...");

try
{
//Start listening to the remoting channel:
RemotingConfiguration.Configure("Client.exe.config ",
false);

Console.WriteLine("Client is now running");

Console.WriteLine("Construct a remote object...");
RemoteObject remoteObject = new RemoteObject();

remoteObject.TaskComplete += listener.TaskComplete;

Console.WriteLine("Perform asynchronous request using
events...");
remoteObject.GetActiveDomainAsychronous();

Console.WriteLine("Perform asynchronous request using
delegates...");

remoteObject.GetActiveDomainAsychronous(listener.T askComplete);
}
catch (Exception e)
{
Console.WriteLine("Error: {0}", e.Message);
}

Console.WriteLine("Press Return to quit...");
Console.ReadLine();
}
}
}
================================

================================
DLL
================================
TaskCompleteEventArgs.cs:
================================
using System;
using System.Collections.Generic;
using System.Text;

namespace DLL
{
[Serializable]
public class TaskCompleteEventArgs : EventArgs
{
private readonly string activeDomain;
private readonly string transmissionType;

public TaskCompleteEventArgs(string activeDomain, string
transmissionType)
{
this.activeDomain = activeDomain;
this.transmissionType = transmissionType;
}

public string ActiveDomain
{
get
{
return activeDomain;
}
}

public string TransmissionType
{
get
{
return transmissionType;
}
}
}
}
================================
EventListener.cs
================================
using System;
using System.Collections.Generic;
using System.Text;

namespace DLL
{
[Serializable]
public class EventListener : MarshalByRefObject
{
public void TaskComplete(object sender, TaskCompleteEventArgs
e)
{
Console.WriteLine("Asynchronous response received using
{0}. Domain: {1}", e.TransmissionType, e.ActiveDomain);
Console.WriteLine("Receiving domain: {0}",
AppDomain.CurrentDomain.FriendlyName);
}

public override object InitializeLifetimeService()
{
//This ensures the listener doesn't die!
return null;
}
}
}
================================
RemoteObject.cs
================================
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

namespace DLL
{
public class RemoteObject : MarshalByRefObject
{
public event EventHandler<TaskCompleteEventArgs> TaskComplete;

public RemoteObject()
{
Console.WriteLine("RemoteObject constructed");
}

~RemoteObject()
{
Console.WriteLine("RemoteObject destructed");
}

public void GetActiveDomainAsychronous()
{
new Thread
(
delegate()
{
Console.WriteLine("Getting active domain using
events...");
Thread.Sleep(3000);
string activeDomain =
AppDomain.CurrentDomain.FriendlyName;
Console.WriteLine("Active domain obtained");
OnTaskComplete(new
TaskCompleteEventArgs(activeDomain, "Events"));
}
).Start();
}

public void
GetActiveDomainAsychronous(EventHandler<TaskComple teEventArgs>
callback)
{
new Thread
(
delegate()
{
Console.WriteLine("Getting active domain using
delegates...");
Thread.Sleep(3000);
string activeDomain =
AppDomain.CurrentDomain.FriendlyName;
Console.WriteLine("Active domain obtained");

try
{
callback(this, new
TaskCompleteEventArgs(activeDomain, "Delegates"));
}
catch (Exception ex)
{
Console.WriteLine("Error while calling
delegate: {0}", ex.Message);
}
}
).Start();
}

protected void OnTaskComplete(TaskCompleteEventArgs e)
{
if (TaskComplete != null)
{
foreach (Delegate d in
TaskComplete.GetInvocationList())
{
try
{
((EventHandler<TaskCompleteEventArgs>)d)(this,
e);
}
catch(Exception ex)
{
Console.WriteLine("Error while raising event:
{0}", ex.Message);
}
}
}
}
}
}
================================

Reply With Quote
Reply




Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off



Powered by vBulletin Version 3.5.4
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.