Tisztelt nagyérdemű!
Szeretném, hogy a kliens alkalmazás elérje a szerver néhány metódusát, ill. változóját, amellett, hogy mindkét oldal egyazon pc-n fut. RMI-vel megoldható ez?
A JBuilderben ismerkedem egy neten talált példával: http://www.cab.u-szeged.hu/WWW/java/kiss/rmi.html
A szerver indítsakor akad meg, úgy gondolom, hogy a Naming() beállításai lehetnek rosszak. Így néz ki:
AlarmServerImpl server = new AlarmServerImpl("AlarmServer"); Naming.rebind("rmi://localhost:1099/AlarmServer", server);
Az RMIRegistry el van indítva! A szerver- és kliens csonk is le va generálva.
Kérlek segítsetek! Lehetőség szerint példákal is...
Köszönettel:
Z
Page
viewed times
#trackbackRdf ($trackbackUtils.getContentIdentifier($page) $page.title $trackbackUtils.getPingUrl($page))
16 Comments
Unknown User (kedzol)
köszönet az előző témában nyújtott segítségért! És ím itt a következő gond: Az RMIServer futtatja a MainScene nevű osztályt, amely tartalmazza a Java3D virtuális világot... A kliensnek ezt át akarom adni. A kapcsolat fel is épül, csak az átvitel nem sikeres, kapok egy ilyen hibaüzenetet:
tehát Serializálhatóvá teszem a MainScene osztályt, de ekkor: Meddig menjek el, az Object-ig???? :(
Ugyanez a helyzet áll elő, mikor az adatbázist akarom átadni. Miután az adb-t tartalmazó csomagom összes osztálya serializálható lett, akkor elindul egy szinttel feljebb... Mi a megoldás?
Kérlek segítsetek!!
üdv
Z
Auth Gábor
Értelemszerűen mindent távolról meghívott metódus paraméterlistájában és visszatérési értékében lévő osztálynak implementálnia kell a Serializable interfészt... Egy picit mesélhetnél a projektedről, hátha jobban el tudunk igazodni a poblémádban... :)
tvik
van még egy varázsszó, amit érdemes ismerni, ez pedig a "transient". Ha van egy osztályod, ami olyan másik objektumhoz csatlakozik amit már nem akarsz átküldeni az RMI-n akkor a transient módosítót kell használni. Pl:
Ekkor a "conn" objektum és az összes hozzá kapcsolódó objektum (gyakorlatilag az egész adatbázisszerver) nem lesz átküldve a hálózaton, hanem default értéket kap a másik oldalon. (null) Ebből adódik, hogy a másik oldalon a MyObject-nek nem tudod elérni a teljes funkcionalitását. Úgyhogy először is át kell gondolni, hogy melyek azok az objektumok amiket okvetlenül át akarsz nyomni a hálózaton és mi az amit távoli elérésre akarsz szánni.
A másik dolog, hogyha teljes osztálykönyvtárakat akarsz átadni, akkor codebase-t érdemes megadni, ahonnan a kliens letöltheti azokat. Ha az egész "3d világ adatbázist" akarod RMI-n keresztül átadni, ott lehet hogy baj van egy kicsit a koncepcióval.
Unknown User (frimen)
Szerintem probáld meg az egész számitógépet kiegésziteni a Serializable interfésszel és add át azt! Mi a fenének pitizel adatbázis, meg Java3D átatdással! :-)
Fri
Auth Gábor
Khm... :)
Unknown User (kedzol)
Unknown User (kedzol)
szóval:
Canvas3D amire rajzolunk
Locale a színtérgráf gyökere. Erre láncolunk fel mindent: transzformációk, modellek, fények...
Úgy gondoltam, hogy a szerveren folyamatosan fut, várja a jelentkezőket. ezen kívül még fut rajta az adb aztán slussz. A kliens hozza létre az ablakokat (Main, Karakter, Help stb.), és meg kell tudni hívnia legalább a vásznat és a locale-t, hogy megjeleníthesse, de hát ezek valóban nem serializalhatóak...
Remélem így már érthetőbb egy kicsit a probléma, vagy előbukkanhat egy megoldás. Ha valami van írjatok!
Z
Auth Gábor
Meg kellene ismerned és használnod kellene az MVC filozófiát, mert itt eléggé nagy kavarodás van, ahogy látom... :)
Kell egy (vagy több) View. Ez az, amit a felhasználó lát, vagyis ennek és csakis itt és csakis ennek kell lennie a Java3D osztályoknak. Ez lehet egy applet, amelyet a böngésző futtat, vagy lehet akár egy alkalmazás is. Minden megjelenés itt történik.
Kell egy és csakis egy Model. Ez az, ahol a megjelenítendő adatokat és a (később leírt) vezérléshez szükséges ismereteket tároljuk. Célszerűen egy adatbázis, vagy bármilyen perzisztens tároló.
Kell minden View mögé egy Control. Ennek a dolga, hogy a View által mutatottakat szinkronban tartsa a Model tartalmával. Ha a Model változik, a Control aktuálizálja a megjelenítést, ha pedig a megjelenítésen keresztük jön egy parancs, akkor azt végrehajtja a tárolt adatokon.
A Java ezen az MVC modellen alapul, a Swing teljesen (utálják is sokan ezért... :), és a Java3D is ezen keresztül kezelendő. :)
A lényeg, hogy ez rajtad így nem segít... mikor kell leadnod a szakdogát? Mert addigra gatyába kellene rázni ugye... :)
Unknown User (kedzol)
Hát valóban tapasztalatlan vagyok, 3 félév Java után nem is olyan nagy csoda. Hallottam az MVC-ről de csak érintőlegesen szóltak róla, kb annyit, mint te itt. Avass be légyszives, honnan látod egy osztályt megnézve, hogy kavarodás van? Ha téma nem is segít a helyzet megoldásában szívesen elsajátítanám az MVC modellt, ugyhogy ha van valami jó anyagod küld el kérlek.
Visszatérve a felvetett problémára: A gond az, hogy az RMI-vel átvivendő objektumok nem serializálhatóak. Megpróbálkoztam a Canvas3D osztállyal is, a dokumentációban ez áll: mégis a következő hibaüzenetet kapom:
mi a véleményed?
A leadási határidő egyébbként jövő hét hétfő! Kicsit szorít az idő. Igaz, hogy már csak ezt kell megoldani, a többi funkció okés.
üdv Zoli
Auth Gábor
Szerintem 6 nap alatt nem tudod úgy átstruktúrálni a programod szerkezetét, hogy MVC szerint dolgozzon, hiszen a program modellje helyett egy alapvetően View célú osztálykönyvtárad van (a Java3D).
Önmaga az, de lehet, hogy benne lévő egyéb kapcsolatok már nem azok... Egy Canvas3D-t eléggé esélytelen áthúzni hálózaton, hiszen rajta csüng egy teljes J3D univerzum, amelyeket nem tud az RMI átvinni, mert nem feladata. Ha a másik oldalon egy ilyen Canvas3D-t deserializálnál, akkor egy csomó belső metódusa lógna a levegőben, mert meghívnának olyan példányok metódusait, amelyeket az RMI nem tudott áthúzni (szerintem nem is képes rekurzíve osztályt szerializálni, de javítson ki valaki).
Akkor erre kellene koncentrálni.
Nézzük előlről. Van a programodnak egy olyan része, amely létrehoz egy J3D univerzumot, annak gyökerét (a Canvas3D-t) vagy részeit RMI-vel elérhetővé teszi, majd a kliens gyakorlatilag egy üres panel, amire kitennéd az RMI-vel áthúzott Canvas3D-t.
Ha így van, akkor ez esélytelen. A J3D Canvas3D példánya folyamatosan billentyűzet és egér eseményeket akar küldeni a szerver felé (de nem tud, mert az RMI erre nem jó), és folyamatosan kérdezi az alatta lévő univerzumot, hogy a benne lévő tárgyakat ábrázolni tudja (de nem tudja kérdezni, mert nincs folyamatos RMI kapcsolat).
Valahogy másképp kellene megoldani... az RMI olyan, mint a HTTP protokoll: indul egy kérés, a szerver erre ad egy választ. De nincs állandó kapcsolat. HTTP sem tud olyan dolgokat, amik állandó kapcsolatot igényelnek, folyamatos a kérdés-válasz mind-mind új HTTP kérést jelent.
A kérdés az, hogy mi a szakdolgozat vállalt témája, és mennyire lehet a kész kódot átforgatni olyanná, hogy ez kivitelezhető legyen.
tvik
A szerveren van a modell. A szerver tartalmazza egy adatbázisban, vagy ő számolja ki szimulációval hogy mi hol van a térben, de fogalma sincs, hogy hogyan kell kirajzolni. Tehát a szerveren (a modellben) egyáltalán nincsenek a megjelenítéssel foglalkozó kódrészek, hiszen a modell nem tudja, hogy hogyan fogják megjeleníteni. Ilyet hogy Canvas, le sem szabad írni a szerveren, sehol. Egy modellt meg lehet jeleníteni sokféleképpen (többféle 3d mtor, vagy akár paraméteres megjelenítés), az MVC lényege, hogy ezt leválassza a modellről. A modellnek vannak olyan lekérdező metódusai, amik a modell pillanatnyi állapotát vagy részállapotát tudják visszaadni. Pl. List getNearbyObjects(double x, double y, double z) - visszaadja a közeli objektumokat. Fontos még, hogy ne legyen túl sok vagy túl bonyolult lekérdező metódus. Maga a modell állhat rengeteg osztályból és lehet tetszőlegesen bonyolult, de legyen egy egyszerű, kevés metódust tartalmazó osztály benne, amin az aktuális állapotát le lehet kérdezni. (Ez a facade/homlokzat minta.) Ez a felület fog megjelenni a távoli elérésre szánt osztályban, ami a szerver elérési pontja.
A kliensen van a view (nézet). A view tartalmazza a megjelenítő logikát, de hogy konkrétan mit jelenít meg (magukat az adatokat) azt teljes egészében a modellből veszi. Szóval a view hívogatja a modell getNearbyObjects() metódusát és kirajzolja szépen a saját canvas-ára a visszaadott dolgokat. Ebből adódik, hogy a View alatt pedig lecserélhető a modell, de ez most mellékes. Nagyjából a kliensen van az egész 3d java csomag.
A Controller is mellékes most.
Ebben az esetben a view és a modell között RMI kapcsolat van. A kapcsolaton csak egyszerű adatok vándorolnak, amik a modell állapotát reprezentálják. (Ezeket hívják transzfer objektumnak.) Ilyesmik, hogy 0,0,0 koordinátán van egy fa, 10, 4, 6 koordinátán van egy autó, az ég textúrája (bitmap). Ezeknek kompakt és Serializable objektumoknak kell lenniük. A kompakt azt jelenti, hogy nem kapcsolódnak semmihez, magukban értelmesek, minden szükséges adatot tartalmaznak amit át kell vinni a hálózaton. Pl. az nem jó, hogy egy transzfer objektum egy fájlnevet tartalmaz, mert a fájlnevet hiába viszed át a hálózaton, a szerver és a kliens gépen nem ugyanaz a fájlrendszer. Ilyen esetekben a fájl konkrét tartalmát kell tartalmaznia a transzfer objektumnak.
Tehát a lényeg a modell és a view szétválasztása, egyszerű transzfer objektumok és egyszerű facade felület a modellen.
tvik
Ha járatos vagy az RMI alapjaiban, tudod hogy kell definiálni egy távoli interfészt, amit a távoli elérésre szánt objektumnak (a szervernek) implementálnia kell. A kliens pedig ezt az interfészt hívogatja, az RMI rendszer pedig gondoskodik róla, hogy a hívások átmenjenek a hálózaton.
Talán nem túl meglepő módon, a modell homlokzata, amit említettem hogy egyszerű kell hogy legyen, pont alkalmas ilyen távoli interfésznek. Például: Szóval az MVC minta pont szépen beleillik az RMI koncepciójába.
Auth Gábor
tvik
Kasza Miklós
Harom dolog fog kelleni:
1. szerver oldalra olyan osztalyok, amelyeket te keszitesz, es szerializalhatoak (adattagjaikkal es az egymashoz valo kapcsolataikkal leirjak a teljes vilagot - anelkul, hogy a megjelenites modjaval tenylegesen foglalkoznal)
2. szerver oldalra olyan osztalyok, amelyek RMI-interfeszeket valositanak meg, es az 1. pontban leirt osztalyokbol szarmazo objektumokat lehet veluk (metodusaikkal) tologatni fel-le (nyilvan kliens oldalra is kellenek osztalyok, amik ezeket hivogatjak, de ez most nem is volt kerdeses)
3. kliens oldalra mehet a teljes Java3D, de azt meg kell oldanod valahogy, hogy az altalad letrehozott objektumok (1. pont) alapjan Java3D objektumokat hozz letre
Igyekeztem tomor, es vilagos lenni, remelem sikerult :)
Auth Gábor
Abszolút megoldható RMI-vel, de a változókat nem lehet elérni, csak metódusokat lehet hívni. Változókat getter metódusokkal tudod elérni. Lehet hogy úgy is jó ahogy te próbálod, én így szoktam szervert csinálni (rmiregistry programot nem kell kézzel elindítani):
Az 1.5-ös verziótól (ha a kliens és a szerver is 1.5 vagy késpbbi) már nem kell használni az rmic-t, mert a csonk osztályokat dinamikusan generálja futási időben.