Discussion:
[omniORB] omniORBpy + wxPython; omniORBpy + Twisted
charles bartlett
2007-12-28 06:10:57 UTC
Permalink
I searched the mail archives but did not find a response to this request
from 8/19/06:

"
Hello,

is there something like an introduction manual/textbook/tutorial about
client/server programming using omniorbpy for non-computer scientists?

Especially concerning aspects like the integration with common GUI
frameworks
such as wxpython, pyQt, pyGTK etc...

Alternatively/additionally, is there something like a "cookbook"
example
application with well documented source code?

TIA,

Sincerely,

Wolfgang Keller
--
My email-address is correct.
Do NOT remove ".nospam" to reply.

"


Twisted documentation specifically addresses integration with GUI
toolkits:
http://twistedmatrix.com/projects/core/documentation/howto/choosing-reactor.html

I am looking for something similar for omniORBpy, although it could run
in a thread other than the GUI event loop.

Alternatively, please provide a pointer to how to interface omniORBpy to
Twisted, i.e. send data from a CORBA client to the omniORBpy to the
Twisted framework to a Twisted server faithfully.

Thanks.
Stephen Hansen
2007-12-28 14:26:37 UTC
Permalink
Post by charles bartlett
I am looking for something similar for omniORBpy, although it could run
in a thread other than the GUI event loop.
Alternatively, please provide a pointer to how to interface omniORBpy to
Twisted, i.e. send data from a CORBA client to the omniORBpy to the
Twisted framework to a Twisted server faithfully.
I'm not sure what you're asking, exactly.

You don't have to do anything special to use omniORBpy with anything. You
don't actually have to ever run "orb.run()" and enter an event loop to use
it; all you have to do is register servants with a POA, and use
poa._get_the_POAManager().activate(). Unlike twisted, there's no separate
event loop to maintain and integrate at all.

omniORB automatically runs in any number of threads seamlessly with no
effort required from you. It handles connections, spawns threads, and does
everything itself internally.

The only thing you have to worry about is having code instigated from
omniORB interacting with the GUI. In this case, you use "wx.CallAfter" to
control the GUI and send changes to it.

So if you get a chunk of data in a CORBA object and want it to trigger a
change in your GUI, you "wx.CallAfter(self.control,argument)" instead of "
self.control(argument)" and the GUI will process it.

I can give more specific details, as we use omniORB and wxPython extensively
... but need more specific questions.

--Stephen
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.omniorb-support.com/pipermail/omniorb-list/attachments/20071228/c08eb97c/attachment.htm
charles bartlett
2007-12-28 19:24:44 UTC
Permalink
Stephen,

Thanks for your instructive response.

As you "use omniORB and wxPython (together) extensively" and have
provided an outline of how to use them together, I will code an example
and ask more specific questions as they arise later. The exercise will
be instructive.

It would be better to have a pointer to an example already constructed.
If that is not readily available in omniORB documentation, then perhaps
it should be. (I am not asking you to construct such an example!) By
comparison, the wxPython demo program is very good because it
immediately shows, with little effort, the various capabilities of
wxPython and basically how to code them.


Thanks to the omniORB developer(s) for reducing the barrier to using
CORBA to a learning curve and for the pointer to its "simple
explanation".
Post by charles bartlett
I am looking for something similar for omniORBpy, although it could run
in a thread other than the GUI event loop.
Alternatively, please provide a pointer to how to interface omniORBpy to
Twisted, i.e. send data from a CORBA client to the omniORBpy to the
Twisted framework to a Twisted server faithfully.
I'm not sure what you're asking, exactly.
You don't have to do anything special to use omniORBpy with anything.
You don't actually have to ever run " orb.run()" and enter an event
loop to use it; all you have to do is register servants with a POA,
and use poa._get_the_POAManager().activate(). Unlike twisted, there's
no separate event loop to maintain and integrate at all.
omniORB automatically runs in any number of threads seamlessly with no
effort required from you. It handles connections, spawns threads, and
does everything itself internally.
The only thing you have to worry about is having code instigated from
omniORB interacting with the GUI. In this case, you use "wx.CallAfter"
to control the GUI and send changes to it.
So if you get a chunk of data in a CORBA object and want it to trigger
a change in your GUI, you "wx.CallAfter(self.control,argument)"
instead of " self.control(argument)" and the GUI will process it.
I can give more specific details, as we use omniORB and wxPython
extensively ... but need more specific questions.
--Stephen
charles bartlett
2008-01-02 11:28:14 UTC
Permalink
Stephen,

I attached a file that can replace example_echo_srv.py when running the
stringified echo example from the omniORBpy examples. It demonstrates
that your suggested mechanism works and fills in some of the missing
details.

To run:
- open two terminals
- in term1 type: python example_echo_srv_wxpython.py
you should now see the "simple button example" window; press 'Send' to
note the text window update.
- copy the IOR from term1, it starts with 'IOR:xxx...xxx'; should be
able to do this without killing the "simple button example" window
- in term2 type: python example_echo_clt.py IOR:xxx...xxx; where you
paste in the IOR that was copied from term1; you should see 'Hello from
Python' in the text window update
- now you can mix pressing 'Send' or rerunning the term2 command as you
like to note the independent operation of the wxpython event loop and
the omniORB updates

You have to copy over the IOR everytime you restart the server, as it
changes apparently. It is easier to send this to a file and read it, but
this is a quick little example.

I like to be explicit in the above, to save time for those who are
trying these examples.

I suppose one can infer from this example that it is feasible (using the
mechanism you suggested) to drive any wxPython widget as the output of a
CORBA call from some remote client, which was my interest.

I ran the above on Ubuntu; I did not try it on Windows.

Thanks again for your instructive suggestion - you saved me some time
searching around. I hope my example will likewise be helpful to someone
else.

BTW, I did not look at the tic-tac-toe example in detail yet, but it did
not appear to use the mechanism you suggested as it does not call
wx.CallAfter.

You will also note that this example does no explicit registration of
servants with a POA, it simply extends Example__POA.Echo. So, maybe I am
missing something here.

Note that the attached file has a specific ordering of the wxPython and
omniORBpy code; violate the ordering and you may incur an error.

Charles
Post by charles bartlett
Stephen,
Thanks for your instructive response.
As you "use omniORB and wxPython (together) extensively" and have
provided an outline of how to use them together, I will code an example
and ask more specific questions as they arise later. The exercise will
be instructive.
It would be better to have a pointer to an example already constructed.
If that is not readily available in omniORB documentation, then perhaps
it should be. (I am not asking you to construct such an example!) By
comparison, the wxPython demo program is very good because it
immediately shows, with little effort, the various capabilities of
wxPython and basically how to code them.
Thanks to the omniORB developer(s) for reducing the barrier to using
CORBA to a learning curve and for the pointer to its "simple
explanation".
Post by charles bartlett
I am looking for something similar for omniORBpy, although it could run
in a thread other than the GUI event loop.
Alternatively, please provide a pointer to how to interface
omniORBpy to
Twisted, i.e. send data from a CORBA client to the omniORBpy to the
Twisted framework to a Twisted server faithfully.
I'm not sure what you're asking, exactly.
You don't have to do anything special to use omniORBpy with anything.
You don't actually have to ever run " orb.run()" and enter an event
loop to use it; all you have to do is register servants with a POA,
and use poa._get_the_POAManager().activate(). Unlike twisted, there's
no separate event loop to maintain and integrate at all.
omniORB automatically runs in any number of threads seamlessly with no
effort required from you. It handles connections, spawns threads, and
does everything itself internally.
The only thing you have to worry about is having code instigated from
omniORB interacting with the GUI. In this case, you use "wx.CallAfter"
to control the GUI and send changes to it.
So if you get a chunk of data in a CORBA object and want it to trigger
a change in your GUI, you "wx.CallAfter(self.control,argument)"
instead of " self.control(argument)" and the GUI will process it.
I can give more specific details, as we use omniORB and wxPython
extensively ... but need more specific questions.
--Stephen
-------------- next part --------------
A non-text attachment was scrubbed...
Name: example_echo_srv_wxpython.py
Type: text/x-python
Size: 1416 bytes
Desc: not available
Url : http://www.omniorb-support.com/pipermail/omniorb-list/attachments/20080102/5a18fba6/example_echo_srv_wxpython.py
Stephen Hansen
2008-01-02 14:54:31 UTC
Permalink
Post by charles bartlett
- open two terminals
- in term1 type: python example_echo_srv_wxpython.py
you should now see the "simple button example" window; press 'Send' to
note the text window update.
- copy the IOR from term1, it starts with 'IOR:xxx...xxx'; should be
able to do this without killing the "simple button example" window
- in term2 type: python example_echo_clt.py IOR:xxx...xxx; where you
Post by charles bartlett
paste in the IOR that was copied from term1; you should see 'Hello from
Python' in the text window update
As you work with this more yourself, you'll likely find the desire to move a
lot of the lower-level CORBA details into libraries to repeat a lot of this
common setup stuff that would simplify 'using' omniORB in a lot of these
client-ways. Our 'network' library (recently rewritten) has me calling the
"initialize" function once per app, and it sets up the ORB in a common way,
provides a standard method (beyond arguments-- since I found having users
enter standard CORBA arguments on the command line is simply unacceptable)
for specifying endpoints/name servers, and other magical stuff we've added
over the last couple years.

As you go about doing that, some things I've discovered:

- Be very, very careful of calling CORBA.ORB_init in libraries. You only get
one chance to run it with the arguments passed in, and any further
invocations appear to return the same ORB. I found it helpful having my
"initialize" function remember if its called, and then making re-calling it
raise an exception... then have any other network support library check and
raise an exception if they were called before initialize had been.
- In a wx app, let wx be boss. omniORB deals with everything in such an easy
'back seat' way, I found its best to organize the application and deal with
it as any client wxPython app without focusing on the omni-fu. I just call
that initialize function early on in the setup of said app-- usually in the
wxApp's OnInit method. Just always remember: when sending data back to the
GUI, use wx.CallAfter.
- You can call poaManager.activate() anytime; doing so right away as soon as
you initialize the ORB and snag the poa, even before you go about making
servants (that 'ei' is) is helpful (but not necessary). Doing so appears to
be the key catalyst that lets the poa start handling actual requests, but if
there's no requests to handle early, so what. :) I say that because I've
been bitten in forgetting to call it, until I started calling it in the
initialization routine early on :)

You have to copy over the IOR everytime you restart the server, as it
Post by charles bartlett
changes apparently. It is easier to send this to a file and read it, but
this is a quick little example.
Yeah, it changes everytime; the POA (or the ORB? Or the PoaManager? or
servant itself? I'm not entirely sure on the internals of what does what in
omniORB or CORBA :)) gets a random IP address every invocation. This
actually ends up being quite helpful in certain ways down the road, I've
found. In other ways its vexing. It is a factor to take into consideration
in the design of the application.

You'll likely want to do one of three things in a real app:

1) Set up a Naming Service (omniNames is good, though I use TAO's NT Naming
Service as it is rock solid and runs as a service easily, and our clients
run windows/mac os x primarily) and 'register' this IOR so that other
components/machines can find it (what name you use depends on your app)
2) Specify -ORBendPoint arguments either via the command line or by adding
them to sys.argv passed into ORB_init yourself; this will force a certain
port which will usually have the effect of making a IOR to that computer
keep working as future invocations won't get a random port, but this
specified one.
3) Use an omniINSPOA. This is very nice, but you have to use it carefully;
as much as you'd like to at first you can't create a child POA of it with
different policies. It's best used, I've found, as just a starting point
into an application. You create a very simple interface, "Connector", that
only has two methods on it. One that 'sets' your main interface, and one
that 'gets' it. When your application starts up, you create an Echo_i
servant, and a Connector_i servant. One you're going to use with the
omniORBINSPOA, the other you're going to use with the regular POA.

You then call Echo_i's "set" method with Connector_i's object reference.

That omniINSPOA servant allows you to specify objects by an explicit name.
So you could have your client object reference your server one with a simple
name such as "corbaloc:127.0.0.1:12345/Connector" -instead- of an IOR. That
will always be the same.

It'd be like:
con = orb.string_to_object("corbaloc:127.0.0.1:12345/Connector")
es = con.get()
es.echoString("Hi!")

Those are all very general, I know. There's some good postings on how to
work it around, and I can provide more concrete examples when you get there
:) Which method you do depends on your app... we have a full-blown
application server in python + omniORB with dozens to hundreds of clients
connected to it, and then multiple clients per machine that talk to
each-other. For some of those connections we use a naming service; for some
we use the INSPOA, etc.
Post by charles bartlett
I suppose one can infer from this example that it is feasible (using the
mechanism you suggested) to drive any wxPython widget as the output of a
CORBA call from some remote client, which was my interest.
Yea, you can;
Post by charles bartlett
I ran the above on Ubuntu; I did not try it on Windows.
It -looks- right so it should work on windows and mac also.
Post by charles bartlett
BTW, I did not look at the tic-tac-toe example in detail yet, but it did
not appear to use the mechanism you suggested as it does not call
wx.CallAfter.
I'm not actually familiar with it; there's alternatives to using
wx.CallAfter.
One is to use a queue, and have an idle loop in the wx thread that checks
that
queue-- but that's what wx.CallAfter does behind the scenes so there's
really no
reason to do that :)
Post by charles bartlett
You will also note that this example does no explicit registration of
servants with a POA, it simply extends Example__POA.Echo. So, maybe I am
missing something here.
I use a LOT of "default servants" in my servers-- they save resources and
time and make things easy. And I don't use implicit activation, as it makes
things more complicated if you use more then one POA... like the regular one
or the INS poa.

So in my server initialization code, I do:

defaultRootPOA = orb.resolve_initial_references("RootPOA")
policies = [
defaultRootPOA.create_implicit_activation_policy(
PortableServer.NO_IMPLICIT_ACTIVATION),
]

pman = defaultRootPOA._get_the_POAManager()
pman.activate()
rootPOA = defaultRootPOA.create_POA("motherPOA", pman, policies)

My new poa, a child of the original, doesn't do implicit activation.

My servant would then be initialized as:

echoServant = Echo_i(orb, rootPoa)
rootPoa.activate_object(echoServant)

Later when using the INS poa, that'd be 'activate_object_with_id' to give
that servant a specific name, etc.

Note that the attached file has a specific ordering of the wxPython and
Post by charles bartlett
omniORBpy code; violate the ordering and you may incur an error.
I'm not sure what error would be the problem with doing things in a
different order, but I'd naturally do all the network initialization inside
the wxApp's initialization. Just seems natural; wx is boss :) omniORB Just
Works :)

Anyhoo, glad to help. I can help with more specific examples later.

--Stephen.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.omniorb-support.com/pipermail/omniorb-list/attachments/20080102/dcb7b633/attachment-0001.htm
charles bartlett
2008-01-06 23:56:49 UTC
Permalink
Stephen,

Attached is an example of bidirectional communication between two
processes each running a wxPython window.

Run omniidl -bpython example_echo.idl

Start two terminals:
type 'python echo_clt_srv_wxpython1.py' in one terminal
type 'python echo_clt_srv_wxpython2.py' in other terminal

You should see two wxPython windows; press Send button on either to send
message to the other process.

Note the two programs use the same idl definition. Also, the dummy
reference to sb to get things started sharing the IORs. Also, the
symmetry of the two programs.

Charles
Post by charles bartlett
Stephen,
I attached a file that can replace example_echo_srv.py when running the
stringified echo example from the omniORBpy examples. It demonstrates
that your suggested mechanism works and fills in some of the missing
details.
- open two terminals
- in term1 type: python example_echo_srv_wxpython.py
you should now see the "simple button example" window; press 'Send' to
note the text window update.
- copy the IOR from term1, it starts with 'IOR:xxx...xxx'; should be
able to do this without killing the "simple button example" window
- in term2 type: python example_echo_clt.py IOR:xxx...xxx; where you
paste in the IOR that was copied from term1; you should see 'Hello from
Python' in the text window update
- now you can mix pressing 'Send' or rerunning the term2 command as you
like to note the independent operation of the wxpython event loop and
the omniORB updates
You have to copy over the IOR everytime you restart the server, as it
changes apparently. It is easier to send this to a file and read it, but
this is a quick little example.
I like to be explicit in the above, to save time for those who are
trying these examples.
I suppose one can infer from this example that it is feasible (using the
mechanism you suggested) to drive any wxPython widget as the output of a
CORBA call from some remote client, which was my interest.
I ran the above on Ubuntu; I did not try it on Windows.
Thanks again for your instructive suggestion - you saved me some time
searching around. I hope my example will likewise be helpful to someone
else.
BTW, I did not look at the tic-tac-toe example in detail yet, but it did
not appear to use the mechanism you suggested as it does not call
wx.CallAfter.
You will also note that this example does no explicit registration of
servants with a POA, it simply extends Example__POA.Echo. So, maybe I am
missing something here.
Note that the attached file has a specific ordering of the wxPython and
omniORBpy code; violate the ordering and you may incur an error.
Charles
Post by charles bartlett
Stephen,
Thanks for your instructive response.
As you "use omniORB and wxPython (together) extensively" and have
provided an outline of how to use them together, I will code an example
and ask more specific questions as they arise later. The exercise will
be instructive.
It would be better to have a pointer to an example already constructed.
If that is not readily available in omniORB documentation, then perhaps
it should be. (I am not asking you to construct such an example!) By
comparison, the wxPython demo program is very good because it
immediately shows, with little effort, the various capabilities of
wxPython and basically how to code them.
Thanks to the omniORB developer(s) for reducing the barrier to using
CORBA to a learning curve and for the pointer to its "simple
explanation".
Post by charles bartlett
I am looking for something similar for omniORBpy, although it
could run
in a thread other than the GUI event loop.
Alternatively, please provide a pointer to how to interface
omniORBpy to
Twisted, i.e. send data from a CORBA client to the omniORBpy to the
Twisted framework to a Twisted server faithfully.
I'm not sure what you're asking, exactly.
You don't have to do anything special to use omniORBpy with anything.
You don't actually have to ever run " orb.run()" and enter an event
loop to use it; all you have to do is register servants with a POA,
and use poa._get_the_POAManager().activate(). Unlike twisted, there's
no separate event loop to maintain and integrate at all.
omniORB automatically runs in any number of threads seamlessly with no
effort required from you. It handles connections, spawns threads, and
does everything itself internally.
The only thing you have to worry about is having code instigated from
omniORB interacting with the GUI. In this case, you use "wx.CallAfter"
to control the GUI and send changes to it.
So if you get a chunk of data in a CORBA object and want it to trigger
a change in your GUI, you "wx.CallAfter(self.control,argument)"
instead of " self.control(argument)" and the GUI will process it.
I can give more specific details, as we use omniORB and wxPython
extensively ... but need more specific questions.
--Stephen
-------------- next part --------------
A non-text attachment was scrubbed...
Name: echo_clt_srv_wxpython1.py
Type: text/x-python
Size: 2012 bytes
Desc: not available
Url : http://www.omniorb-support.com/pipermail/omniorb-list/attachments/20080106/031a0370/echo_clt_srv_wxpython1.py
-------------- next part --------------
A non-text attachment was scrubbed...
Name: echo_clt_srv_wxpython2.py
Type: text/x-python
Size: 2012 bytes
Desc: not available
Url : http://www.omniorb-support.com/pipermail/omniorb-list/attachments/20080106/031a0370/echo_clt_srv_wxpython2.py
-------------- next part --------------
A non-text attachment was scrubbed...
Name: example_echo.idl
Type: text/x-csrc
Size: 103 bytes
Desc: not available
Url : http://www.omniorb-support.com/pipermail/omniorb-list/attachments/20080106/031a0370/example_echo.bin
Duncan Grisby
2007-12-29 21:21:44 UTC
Permalink
On Thursday 27 December, charles bartlett wrote:

[...]
Post by charles bartlett
I am looking for something similar for omniORBpy, although it could run
in a thread other than the GUI event loop.
There's an example tic-tac-toe game in the examples/tictactoe directory
in the omniORBpy distribution. It uses Tk, but it gives an example of
simple GUI programming with a CORBA client and server.

Cheers,

Duncan.
--
-- Duncan Grisby --
-- ***@grisby.org --
-- http://www.grisby.org --
charles bartlett
2007-12-30 02:44:49 UTC
Permalink
Thanks for the pointer; I'll be interested to see if it follows the same
pattern as suggested by Stephen.
Post by Duncan Grisby
[...]
Post by charles bartlett
I am looking for something similar for omniORBpy, although it could run
in a thread other than the GUI event loop.
There's an example tic-tac-toe game in the examples/tictactoe directory
in the omniORBpy distribution. It uses Tk, but it gives an example of
simple GUI programming with a CORBA client and server.
Cheers,
Duncan.
Loading...