Sorry for the delay, your repros are complex :). Additionally having not used 
Remoting thoroughly in about 4-5 years (and then only having a fairly brief but 
in-depth in certain areas exposure to it) this took me some time to work 
through.

Doing everything programmatically in C# this is where I ended up w/ a solution 
that appears to be what you want, but I'm not sure if this is the same as what 
you're doing.  I also changed the type of the event handler to be a simple 
EventHandler rather than your type.

I think I am doing something slightly different than you.  On the client side 
it sounds like you're marshalling what should be your WKO instead of 
marshalling the listener for the event.  You'll notice in my client I have an 
instance of foo that I Marshal to TalkIsGoodToo and then wire up to the remote 
event handler.  Maybe you actually just have two instances of CallbackSink on 
both the client & server doing something more peer-to-peer.

Server side:

using System;
using System.Collections;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Http;
using System.Runtime.Serialization.Formatters;

class foo{
    public static void Main(string[]args){
        SoapServerFormatterSinkProvider provider = new 
SoapServerFormatterSinkProvider();
        provider.TypeFilterLevel = TypeFilterLevel.Full;
// Creating the IDictionary to set the port on the channel instance.
        IDictionary props = new Hashtable();
        props["port"] = 8086;

        ChannelServices.RegisterChannel(new HttpChannel(props, null, provider), 
false);
        WellKnownServiceTypeEntry wkoe = new 
WellKnownServiceTypeEntry(typeof(CallbackSink), "SayHello", 
WellKnownObjectMode.Singleton);
        RemotingConfiguration.RegisterWellKnownServiceType(wkoe);

        Console.WriteLine("server running");
        //CallbackSink cbs = 
(CallbackSink)System.Runtime.Remoting.RemotingServices.Marshal(typeof(CallbackSink),
 "SayHello");
        //cbs.Send("Server Hello");

        Console.ReadLine();
    }
}

Client side:

using System;
using System.Collections;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Services;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Http;
using System.Runtime.Serialization.Formatters;

class foo : MarshalByRefObject{

    public static void Main(string[]args){
        SoapServerFormatterSinkProvider provider = new 
SoapServerFormatterSinkProvider();
        provider.TypeFilterLevel = TypeFilterLevel.Full;
        IDictionary props = new Hashtable();
        props["port"] = 8087;

        ChannelServices.RegisterChannel(new HttpChannel(props, null, provider), 
false);

        Console.WriteLine("go");
        CallbackSink cbs = 
(CallbackSink)System.Activator.GetObject(typeof(CallbackSink), 
"http://localhost:8086/SayHello";);

        foo f = new foo();
        System.Runtime.Remoting.RemotingServices.Marshal(f, "TalkIsGoodToo");
        cbs.OnHostToClient += f.MyEventHandler;
        cbs.Send("hello!");
    }

    public void MyEventHandler(object sender, EventArgs e){
        Console.WriteLine("MyEventHandler!");
    }
}


Then my Python script ends up looking like this:

import System
import clr
clr.AddReference('System.Runtime.Remoting')
clr.AddReference('System.Runtime.Serialization.Formatters.Soap')
from System.Runtime.Serialization.Formatters import TypeFilterLevel
provider = System.Runtime.Remoting.Channels.SoapServerFormatterSinkProvider()
provider.TypeFilterLevel = TypeFilterLevel.Full
props = System.Collections.Hashtable()
props["port"] = 8087

System.Runtime.Remoting.Channels.ChannelServices.RegisterChannel(System.Runtime.Remoting.Channels.Http.HttpChannel(props,
 None, provider), False)

clr.AddReferenceToFile('ro.dll')
import CallbackSink

cbs = System.Activator.GetObject(CallbackSink, "http://localhost:8086/SayHello";)

class foo(System.MarshalByRefObject):
    def handler(self, sender, args): print 'called'

f = foo()

System.Runtime.Remoting.RemotingServices.Marshal(f, "TalkIsGoodToo")
cbs.OnHostToClient += f.handler

and depending on how I tweak things, I finally get an exception of one sort on 
the final line.  For starters I got that ModuleScope was not serializable.  I 
changed it to derive from MarshalByRefObject (not sure that's right, just 
wanted to see about getting past this) and I was able to get a little bit 
further, but this is where it starts to get difficult to make any forward 
progress.

For starters cbs, being a remote MarshalByRefObject, has all the same problems 
w/ remote MarshalByRefObject's that you ran into previously.  I was able to get 
closer to wiring up the event handler by doing:

CallbackSink.OnHostToClient.__get__(cbs, CallbackSink).__iadd__(f.handler)

But then we seem to hit a brick wall where we fail to serialize something else, 
and it's not very clear what it is...

So, the question then becomes, how do you actually do this w/ IronPython?  I 
think what you'll need to do is setup a helper class that can do the event 
handling for you.  Link that against IronPython.dll and call through Ops to 
invoke your object, I came up with:

using System;
using IronPython.Runtime.Operations;

public class Helper : MarshalByRefObject {
    private object o;
    public Helper(object o){
        this.o = o;

    }

    public void Register(CallbackSink cbs){
    cbs.OnHostToClient += this.OnCalled;
    }

    public virtual void OnCalled(object sender, EventArgs e){
        Console.WriteLine("Helper.OnCalled");
        Ops.Call(o);
    }
}

(note the registration does need to occur via C#).

Finally I use that from Python like:

import System
import clr
clr.AddReference('System.Runtime.Remoting')
clr.AddReferenceToFile('helper.dll')
#clr.AddReference('System.Runtime.Serialization.Formatters.')
from System.Runtime.Serialization.Formatters import TypeFilterLevel
provider = System.Runtime.Remoting.Channels.BinaryServerFormatterSinkProvider()
provider.TypeFilterLevel = TypeFilterLevel.Full
props = System.Collections.Hashtable()
props["port"] = 8087

System.Runtime.Remoting.Channels.ChannelServices.RegisterChannel(System.Runtime.Remoting.Channels.Tcp.TcpChannel(props,
 None, provider), False)

clr.AddReferenceToFile('ro.dll')
import CallbackSink

cbs = System.Activator.GetObject(CallbackSink, "Tcp://localhost:8086/SayHello")

def myCallback():
        print 'called'

import Helper
f = Helper(myCallback)
System.Runtime.Remoting.RemotingServices.Marshal(f, "TalkIsGoodToo")
f.Register(cbs)

CallbackSink.Send(cbs, 'hello')


All in all I'd say that IronPython is capable w/ some effort of consuming 
remoting objects, but that we're not capable of producing remotable objects 
(which is what you're effectively trying to do here).  So as you get into the 
more production side of things you'll need some C# code to stitch things 
together.  Hopefully we can do a better job here in the future (although it's 
not entirely clear how) but unfortunately we probably won't make any 
significant changes to this for v1.0.



-----Original Message-----
From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Ralph Soons
Sent: Wednesday, June 21, 2006 12:49 AM
To: [email protected]
Subject: Re: [IronPython] Remoting: Marshal object

In c# I have 3 assembly's. There's a server exe and a client exe and a library 
in which the remoting objects are implemented, which are included in both the 
client and the server. The CallbackSink class is situated in the library which 
has the namespace RemotingServerClient.
I use server activated Singleton mode configuration.

I would like to register on the OnHostToClient event at server side so any 
object registering for this event receives a notification when a client calls. 
My problem was that the object I registered my event to and the object which 
was called by the client weren't the same. So my registered event handlers 
weren't called. That's why I had to use the marshal function.
Using the c# server and client this works.

After this I replaced the c# server by a python server. I used the same 
configuration. Created an event handler function. Created the CallbackSink 
object (got an instance) and registered the event handler to it. Now I marshal 
the callbacksink object to make sure during a call from the client the same 
object is used.

When I call my server in python from the c# client, the message is received in 
the Send function of the CallbackSink and if write the received message to the 
console I see the message appearing in the python console. However the 
CallbackSink object is newly created and isn't the object I marshalled in the 
python server.

So it looks like the Marshal call doesn't work. I don't see any exception.
Only thing I see is that the objects are different.


>From: Dino Viehland <[EMAIL PROTECTED]>
>Reply-To: Discussion of IronPython <[email protected]>
>To: Discussion of IronPython <[email protected]>
>Subject: Re: [IronPython] Remoting: Marshal object
>Date: Tue, 20 Jun 2006 09:05:07 -0700
>
>I'm a little lost on this one - what is RemotingServerClient here?  Is
>it a type, an assembly, a namespace?
>
>Also, do you get an exception, or does it just do nothing?
>
>-----Original Message-----
>From: [EMAIL PROTECTED]
>[mailto:[EMAIL PROTECTED] On Behalf Of Ralph Soons
>Sent: Tuesday, June 20, 2006 8:04 AM
>To: [email protected]
>Subject: [IronPython] Remoting: Marshal object
>
>I have a remoting problem again. I want to create an object at server
>side, as singleton so when a call is done at client side, ill get the
>already existing object. I tried it first with a c# server and client.
>
>Can anyone tell me why the marshal function doesn't work, objects on
>server and client side are still different (same code works in c#
>application so configuration is correct):
>
>Client side (Python):
>t = RemotingServerClient.CallbackSink.Instance
>System.Runtime.Remoting.RemotingServices.Marshal(t, 'TalkIsGoodToo')
>
>Server side (c#):
>CallbackSink.Instance.Send("Message");
>
>Remotable object (c#):
>public class CallbackSink : MarshalByRefObject
>     {
>         private static CallbackSink m_Instance = null;
>         public event delCommsInfo OnHostToClient;
>
>         public static CallbackSink Instance
>         {
>             get
>             {
>                 if (null == m_Instance)
>                 {
>                     m_Instance = new CallbackSink();
>                 }
>                 return m_Instance;
>             }
>         }
>
>         private CallbackSink()
>         { }
>
>         public void Send(string message)
>         {
>             OnHostToClient(info);
>         }
>     }
>
>Thanks for your help.
>Best regards,
>Ralph Soons
>
>_________________________________________________________________
>Talk with your online friends with MSN Messenger
>http://www.join.msn.com/messenger/overview
>
>_______________________________________________
>users mailing list
>[email protected]
>http://lists.ironpython.com/listinfo.cgi/users-ironpython.com
>_______________________________________________
>users mailing list
>[email protected]
>http://lists.ironpython.com/listinfo.cgi/users-ironpython.com

_________________________________________________________________
Talk with your online friends with MSN Messenger 
http://www.join.msn.com/messenger/overview

_______________________________________________
users mailing list
[email protected]
http://lists.ironpython.com/listinfo.cgi/users-ironpython.com
_______________________________________________
users mailing list
[email protected]
http://lists.ironpython.com/listinfo.cgi/users-ironpython.com

Reply via email to