Toon posts:

[corba/java/c++] callback over internet

Pagina: 1
Acties:

Verwijderd

Topicstarter
Ik ben bezig een chatserver/client te ontwikkelen in Corba.
De server schrijf ik in c++, de client in java.
De client opent een verbinding met de server via de namingservice.
Mijn bedoeling is om vervolgens de server terug te laten verbinden naar de client, zodat de client gaat wachten op inkomende berichten.
Hiermee voorkom je dat clients moeten pollen op nieuwe berichten, dat is namelijk minder efficient.
Het gaat dus om een callback, zoals bijv. word besproken in deze tutorial:

http://java.sun.com/j2se/...ide/idl/jidlExample3.html

Uiteraard staan de client en de server fysiek op verschillende plaatsen,
maar hier onstaat ook het probleem.
De verbinding naar de server toe werkt perfect, ik kan remote functies aanroepen.
Als ik echter op de server een functie aanroep die op de client staat (via de aangemaakte callback verbinding dus) blijft de functie hangen en gebeurd er verder niets. De server geeft geen foutmeldingen oid, de client zegt na een hele tijd dat de verbinding verbroken is.

Dat lijkt natuurlijk een probleem in de code, maar dat blijkt niet zo te zijn.
Als ik de client namelijk van dezelfde host start als de server, gaat het WEL goed!
Het gaat dus alleen fout als client en server niet op dezelde machine staan.
Ik kan hier niet veel van maken, en ook google geeft weinig uitkomst deze keer.

Dit is het stukje code die de callback aanmaakt:

code:
1
2
3
4
5
6
7
8
listener = new ClientListenerImp(this);
POA rootPOA = POAHelper.narrow(orb.resolve_initial_references("RootPOA"));
rootPOA.activate_object(listener);
rootPOA.the_POAManager().activate();
            
ClientListener ref = ClientListenerHelper.narrow(rootPOA.servant_to_reference(listener));
            
chatConnectionManager.addListener(ref);


Iemand dit probleem wel eens tegengekomen?

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 15-05 06:45
Is je Java applicatie toevallig een applet? In dat geval gaat het mis omdat de server niet kan verbinden met de client. Ook als het een onafhankelijke client is, zou een firewall (die van Windows XP SP 2 bijvoorbeeld) de inkomende verbinding op de client kunnen blokkeren. Je omschrijving van het probleem doet in ieder geval zoiets vermoeden.

Dé oplossing hiervoor is om IIOP 1.2 te gebruiken, waarmee een bidirectionele verbinding geopend kan worden. De server can de requests sturen over de verbinding die de client geopend heeft (en die blijkbaar werkt). Hoe je dit instelt, is afhankelijk van de gebruikte ORB. Belangrijk is dat zowel client als server IIOP 1.2 ondersteunen en ik denk dat het helpt als je ook IIOP 1.2 in je IOR's vermeldt (maar het zou kunnen dat de client en server later alsnog IIOP 1.2 negotiaten).

[ Voor 18% gewijzigd door Soultaker op 28-10-2004 00:17 ]


Verwijderd

Topicstarter
Bedankt voor je reactie :)
Ik gebruik geen applet, en aan de firewall had ik ook al gedacht, maar dit blijkt het niet te zijn (uitzetten levert hetzelfde resultaat op).
Wat ik nog wel als mogelijkheid zie is dat hij stuk gaat op mijn router.
Ik weet niet precies hoe hij de verbinding opbouwd, maar als hij het lokale ip gebruikt bijv. kan hij natuurlijk nooit meer teruggevonden worden door de server.
Maar ik weet niet hoe ik dit verder kan testen, het is maar een wilde gok.

Ik gebruik overigens de laatste versie van omniOrb.
Heb je toevallig een voorbeeld van een bidirectionele verbinding?

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 15-05 06:45
Als je wil voorkomen dat de server lokale IP adressen gebruikt, kun je handmatig je IIOP endpoints configureren. Met omniORB kan dat vrij makkelijk; hoe dat in Java gaat weet ik helaas niet (daar gaat het waarschijnlijk bij mis, als de client wel de server kan bereiken maar niet vice versa.)

Maar het is misschien handiger om eerst uit te zoeken waar het mis gaat. Zet in je omniORB configuratie je tracelevel eens maximaal (50 ofzoiets), dan krijg je alle messages te zien die er heen en weer gestuurd worden. Ik geloof dat daar ook wel IP-adressen en dergelijke bij genoemd worden. Kijk dan eens wat er precies gebeurt met de blokkerende callback?
Verwijderd schreef op 28 oktober 2004 @ 15:57:
Ik gebruik overigens de laatste versie van omniOrb.
Heb je toevallig een voorbeeld van een bidirectionele verbinding?
Daar hoef je niets bijzonders voor te doen. Je kunt IIOP 1.2 aanzetten in de omniORB configuratie, maar hij staat ook by default aan, voor zover ik weet. Je Java ORB moet natuurlijk ook IIOP 1.2 ondersteunen (geen idee of 'ie dat doet, ik neem aan van wel). Als het goed is kun je op een hoge tracelevel wel zien of 'ie de bidirectionele verbinding gebruikt. Bidirectionele verbindingen zijn juist toegevoegd om CORBA te kunnen laten werken door firewalls, dus op zich zou ik zeggen dat het wel zou moeten kunnen werken.

[ Voor 53% gewijzigd door Soultaker op 28-10-2004 18:03 ]


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 15-05 06:45
Ik heb het eens nagekeken en het lijkt er op dat omniORB weliswaar standaard IIOP 1.2 gebruikt, maar geen bidirectionele connecties gebruikt. Die moet je nog expliciet aanzetten. Ik denk dat in de configuratie acceptBiDirectionalGIOP op 1 zetten voldoende is; de Java ORB moet dan ook wel bidirectionele connecties aangaan (het werkt alleen als beide partijen het ermee eens zijn, natuurlijk). Of dat gebeurt en hoe dat moet moet je zelf even uitzoeken (in omniORB is het offerBiDirectionalGIOP, als je wil testen met een C client).

Ik denk trouwens dat de performance over een bidirectionele connectie beter zou kunnen worden als je meerdere calls per connectie toestaat (kun je ook instellen op de server); de server kan immers geen nieuwe connecties openen met de client, als dat nodig blijkt te zijn. (Daardoor zouden zelfs deadlocks kunnen ontstaan.) Als je applicatie redelijk simpel is dan is dat waarschijnlijk niet aan de orde.

Overigens lost dit de bestaande problemen niet op. Het is gek dat je niet terug kunt verbinden met de client als er geen firewalls tussen zitten en de adressen kloppen.

[ Voor 38% gewijzigd door Soultaker op 28-10-2004 20:13 ]


Verwijderd

Topicstarter
Ik kon even een paar dagen niet aan mijn app werken, maar ik ben weer verder gegaan.
Ik heb wat meer opgezocht over bidirectionele verbindingen, en alles wijst erop dat dit inderdaad noodzakelijk is als je client achter een nat router zit (zoals ikzelf).

Ik kan alleen nergens duidelijk vinden hoe je eea in moet stellen. Voorbeelden zijn er wel, maar tot nu toe niets succesvol.

Ik krijg nu deze error:
code:
1
org.omg.CORBA.TRANSIENT:   vmcid: 0x41540000  minor code: 2  completed: No


In omniORB.cfg heb ik
code:
1
acceptBiDirectionalGIOP = 1

gezet.

Verder start ik de server op deze manier op:
code:
1
./ChatServer -ORBInitRef NameService=corbaname::ipserver:10017 &


en de client op deze manier:
code:
1
java SimpleClient -ORBInitRef NameService=corbaloc:iiop:ipserver:10017/NameService -offerBidirectionalGIOP 1


Als ik -offerBidirectionalGIOP 1 weglaat trouwens hetzelfde.

Wat moet ik nog meer doen om het werkend te krijgen?
De foutmelding komt overigens echt pas op de callback, functies OP de server aanroepen werkt wel.

[ Voor 8% gewijzigd door Verwijderd op 03-11-2004 01:57 ]


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 15-05 06:45
Kun je ergens zien of er echt GIOP 1.2 gebruikt wordt? Ik denk namelijk toch dat het daar ergens fout op gaat.

Die transient exception op de server is logisch; transient krijg je voor elke connection failure, in principe.

Verwijderd

Topicstarter
Ik heb inmiddels van iemand anders begrepen (die met hetzelfde probleem zat) dat Java helemaal geen GIOP ondersteund, ook niet in versie 1.5.

Een bidirectionele verbinding met java gaat dus waarschijnlijk niet lukken :(
Erg vervelend overigens, er zijn toch een hoop mensen die achter een nat router zitten.

Iemand enig idee hoe dit eventueel wel met Java zou kunnen?

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 15-05 06:45
Uiteraard wordt GIOP/IIOP wel ondersteund (anders zou je helemaal geen calls kunnen doen buiten het lokale proces); maar wat bidirectionele IIOP betreft heb je gelijk:
Official Specifications for CORBA support in J2SE 1.4
[..]
• CORBA 2.3.1 chapters 13 and 15 define GIOP 1.0, 1.1, and 1.2. The J2SE 1.4 ORB fully supports all versions of GIOP, with the exception that the bi-directional GIOP feature defined in sections 15.8 and 15.9 is not supported.
Het enige alternatief dat ik kan verzinnen is dat de client dan maar moet gaan pollen; echte callbacks zijn immers fundamenteel onmogelijk als de server de client niet kan bereiken. Dat betekent wel dat je je ontwerp fundamenteel moet herzien.

Je kunt jezelf misschien een hoop werk besparen door een standaard CORBA event service te gebruiken (omniEvents bijvoorbeeld, zou goed samen moeten werken met omniORB). Nietemin werkt dat wel anders dan wat je nu bedacht had, natuurlijk.

Erg jammer dat dit niet werkt, inderdaad, want dit beperkt de mogelijkheden om CORBA vanuit Java applets te gebruiken ook nogal.

[ Voor 6% gewijzigd door Soultaker op 03-11-2004 15:57 ]


Verwijderd

Topicstarter
Bijna niet te geloven dat Sun dit niet geimplementeerd heeft, toch wel een behoorlijk kritiek punt lijkt me.
In dit geval ga ik maar gewoon lekker pollen, jammer want dat hoopte ik nou juist niet te hoeven doen.
Wel bedankt voor alle info _/-\o_

  • Eelke Spaak
  • Registratie: Juni 2001
  • Laatst online: 12-05 15:26

Eelke Spaak

- Vlad -

Verwijderd schreef op 03 november 2004 @ 23:04:
Bijna niet te geloven dat Sun dit niet geimplementeerd heeft, toch wel een behoorlijk kritiek punt lijkt me.
In dit geval ga ik maar gewoon lekker pollen, jammer want dat hoopte ik nou juist niet te hoeven doen.
Wel bedankt voor alle info _/-\o_
Of je kan gewoon een eigen protocol over TCP bedenken en dat gebruiken. Echt lastig zal dat niet zijn voor een chat-applicatie, en het heeft als voordeel dat je de Sockets gewoon open kunt laten staan voor bidirectionele communicatie.

TheStreme - Share anything with anyone

Pagina: 1