<div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">To run:<br>- open two terminals<br>- in term1 type: &nbsp;python example_echo_srv_wxpython.py<br>you should now see the &quot;simple button example&quot; window; press &#39;Send&#39; to
<br>note the text window update.<br>- copy the IOR from term1, it starts with &#39;IOR:xxx...xxx&#39;; should be<br>able to do this without killing the &quot;simple button example&quot; window</blockquote><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
- in term2 type: &nbsp;python example_echo_clt.py IOR:xxx...xxx; where you<br>paste in the IOR that was copied from term1; you should see &#39;Hello from<br>Python&#39; in the text window update</blockquote><div><br class="webkit-block-placeholder">
</div><div><br class="webkit-block-placeholder"></div><div><div>As you work with this more yourself, you&#39;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 &#39;using&#39; omniORB in a lot of these client-ways. Our &#39;network&#39; library (recently rewritten) has me calling the &quot;initialize&quot; 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&#39;ve added over the last couple years.
</div><div><br class="webkit-block-placeholder"></div><div>As you go about doing that, some things I&#39;ve discovered:</div><div><br class="webkit-block-placeholder"></div><div>- 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 &quot;initialize&quot; 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.&nbsp;
</div><div>- In a wx app, let wx be boss. omniORB deals with everything in such an easy &#39;back seat&#39; 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&#39;s OnInit method. Just always remember: when sending data back to the GUI, use 
wx.CallAfter.</div><div>- 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 &#39;ei&#39; is) is helpful (but not&nbsp;necessary).&nbsp;Doing so appears to be the key catalyst that lets the poa start handling actual requests, but if there&#39;s no requests to handle early, so what. :) I say that because I&#39;ve been bitten in forgetting to call it, until I started calling it in the initialization routine early on :)
</div><div><br class="webkit-block-placeholder"></div></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">You have to copy over the IOR everytime you restart the server, as it
<br>changes apparently. It is easier to send this to a file and read it, but<br>this is a quick little example.</blockquote><div><br class="webkit-block-placeholder"></div><div>Yeah, it changes everytime; the POA (or the ORB? Or the PoaManager? or servant itself? I&#39;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&#39;ve found. In other ways its vexing. It is a factor to take into consideration in the design of the application.
</div><div><br class="webkit-block-placeholder"></div><div>You&#39;ll likely want to do one of three things in a real app:</div><div><br class="webkit-block-placeholder"></div><div>1) Set up a Naming Service (omniNames is good, though I use TAO&#39;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 &#39;register&#39; this IOR so that other components/machines can find it (what name you use depends on your app)
</div><div>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&#39;t get a random port, but this specified one.
</div><div>3) Use an omniINSPOA. This is very nice, but you have to use it carefully; as much as you&#39;d like to at first you can&#39;t create a child POA of it with different policies. It&#39;s best used, I&#39;ve found, as just a starting point into an application. You create a very simple interface, &quot;Connector&quot;, that only has two methods on it. One that &#39;sets&#39; your main interface, and one that &#39;gets&#39; it. When your application starts up, you create an Echo_i servant, and a Connector_i servant. One you&#39;re going to use with the omniORBINSPOA, the other you&#39;re going to use with the regular POA.&nbsp;
</div><div><br class="webkit-block-placeholder"></div><div>You then call Echo_i&#39;s &quot;set&quot; method with Connector_i&#39;s object reference.&nbsp;</div><div><br class="webkit-block-placeholder"></div><div>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 &quot;corbaloc:
<a href="http://127.0.0.1:12345/Connector">127.0.0.1:12345/Connector</a>&quot; -instead- of an IOR. That will always be the same.&nbsp;</div><div><br class="webkit-block-placeholder"></div><div>It&#39;d be like:</div><div>&nbsp;&nbsp; con = 
orb.string_to_object(&quot;corbaloc:<a href="http://127.0.0.1:12345/Connector">127.0.0.1:12345/Connector</a>&quot;)</div><div>&nbsp;&nbsp; es = con.get()</div><div>&nbsp;&nbsp; es.echoString(&quot;Hi!&quot;)</div><div><br></div><div>Those are all very general, I know. There&#39;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.
</div><div>&nbsp;</div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">I suppose one can infer from this example that it is feasible (using the<br>mechanism you suggested) to drive any wxPython widget as the output of a
<br>CORBA call from some remote client, which was my interest.<br></blockquote><div><br></div><div>Yea, you can;&nbsp;</div><div>&nbsp;</div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
I ran the above on Ubuntu; I did not try it on Windows.<br></blockquote><div><br class="webkit-block-placeholder"></div><div>It -looks- right so it should work on windows and mac also.</div><div>&nbsp;</div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
BTW, I did not look at the tic-tac-toe example in detail yet, but it did<br>not appear to use the mechanism you suggested as it does not call<br>wx.CallAfter.<br></blockquote><div><br class="webkit-block-placeholder"></div>
<div>I&#39;m not actually familiar with it; there&#39;s alternatives to using wx.CallAfter.</div><div>One is to use a queue, and have an idle loop in the wx thread that checks that</div><div>queue-- but that&#39;s what wx.CallAfter
 does behind the scenes so there&#39;s really no</div><div>reason to do that :)&nbsp;</div><div><br></div><div>&nbsp;</div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">You will also note that this example does no explicit registration of
<br>servants with a POA, it simply extends Example__POA.Echo. So, maybe I am<br>missing something here.</blockquote><div><br class="webkit-block-placeholder"></div><div>I use a LOT of &quot;default servants&quot; in my servers-- they save resources and time and make things easy. And I don&#39;t use implicit activation, as it makes things more complicated if you use more then one POA... like the regular one or the &nbsp;INS poa.
<br></div><div><br class="webkit-block-placeholder"></div><div>So in my server initialization code, I do:</div><div><br class="webkit-block-placeholder"></div><div>&nbsp;&nbsp; &nbsp;defaultRootPOA = orb.resolve_initial_references(&quot;RootPOA&quot;)
<br class="webkit-block-placeholder"></div><div><div>&nbsp;&nbsp; &nbsp;policies = [</div><div>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;defaultRootPOA.create_implicit_activation_policy(PortableServer.NO_IMPLICIT_ACTIVATION),</div><div>&nbsp;&nbsp; &nbsp;]</div><div><br class="webkit-block-placeholder">
</div><div>&nbsp;&nbsp; &nbsp;pman = defaultRootPOA._get_the_POAManager()</div><div>&nbsp;&nbsp; &nbsp;pman.activate()</div><div>&nbsp;&nbsp; &nbsp;rootPOA = defaultRootPOA.create_POA(&quot;motherPOA&quot;, pman, policies)</div><div><br class="webkit-block-placeholder">
</div><div>My new poa, a child of the original, doesn&#39;t do implicit activation.&nbsp;</div><div><br></div><div>My servant would then be initialized as:</div><div><br class="webkit-block-placeholder"></div><div><div>&nbsp;&nbsp; &nbsp;echoServant = Echo_i(orb, rootPoa)
</div><div>&nbsp;&nbsp; &nbsp;rootPoa.activate_object(echoServant)<br></div><div>&nbsp;&nbsp; &nbsp;</div><div>Later when using the INS poa, that&#39;d be &#39;activate_object_with_id&#39; to give that servant a specific name, etc.</div><div><br class="webkit-block-placeholder">
</div></div></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">Note that the attached file has a specific ordering of the wxPython and<br>omniORBpy code; violate the ordering and you may incur an error.
<br></blockquote><div><br class="webkit-block-placeholder"></div><div>I&#39;m not sure what error would be the problem with doing things in a different order, but I&#39;d naturally do all the network initialization inside the wxApp&#39;s initialization. Just seems natural; wx is boss :) omniORB Just Works :)
</div><div><br></div><div>Anyhoo, glad to help. I can help with more specific examples later.</div><div><br class="webkit-block-placeholder"></div><div>--Stephen.</div></div>