[Java] object verzenden van Client <-> Server

Pagina: 1
Acties:

  • Feyd-Rautha
  • Registratie: November 2001
  • Laatst online: 02-08-2025
Momenteel ben ik bezig met een primitief chat-systeem (Client en Server)

Mijn server-programma bevat een class Message. Deze class stelt een bericht voor.

Members:
User FromUser (User object)
User ToUser (User object)
String msg


Nu heb ik ook een class UserPool waarin ik al de ingelogde gebruikers verzamel. Deze classe bevat een sendMessage(Message msg) method die dus, zoals je al kon vermoeden, een bericht verzend.

Mijn probleem is nu dat ik een Message-object zou willen kunnen verzenden naar de Client (en ook van Client naar Server).
Ik gebruik daarvoor een ObjectOutputStream.

Maar als ik mijn object heb verzonden naar het client-programma, kent de client het object Message niet natuurlijk.
Ik heb al geprobeerd om mijn Class Message ook in mijn Client-programma te implementeren, maar dan moet ik ook de Class User, Connection, ... ook implementeren en dat lijkt mij veel te omslachtig.

Kunnen jullie mij dus helpen om Custom objecten te versturen.

ps: ik heb al een tutorial gevonden op java.sun.com, maar in deze tutorial wordt er geen gebruik gemaakt van 2 verschillende projecten (wat bij mij wel het geval is)

volgende code-fragmenten ter verduidelijking:
SERVER-SIDE
Class UserPool

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public void sendMessage(Message msg)
  {
    try
    {
      ObjectOutputStream objout = msg.getToUser().getConnection().getObjectOutputStream();

      objout.writeObject(msg);
      objout.flush();
    }
    catch(IOException e)
    {
      e.printStackTrace();
    }
  }


CLIENT-SIDE is helemaal nog niet af.
Class Main
code:
1
2
3
 ObjectInputStream objin = new ObjectInputStream(new BufferedInputStream(s.getInputStream()));

      Message msg = (Message)objin.readObject();


Member-variabelen van Class Message
code:
1
2
3
4
5
6
7
public class Message
{
  //private transient User fromUser;
  //private transient User toUser;

  private String message;
  private String prefix;


die transient was om te proberen

I must not fear. Fear is the mind-killer. Fear is the little-death that brings total obliteration. I will face my fear. I will permit it to pass over me and through me. Where the fear has gone there will be nothing. Only I will remain.


  • whoami
  • Registratie: December 2000
  • Laatst online: 23:04
Kun je die nodige classes niet 'importen' in uw client-programma?

Je hebt dan de classes:
User, Connection, ....

en je hebt uw 2 projecten, Server en Client. En in beide projecten import je de nodige classes?

https://fgheysels.github.io/


  • Feyd-Rautha
  • Registratie: November 2001
  • Laatst online: 02-08-2025
Dat was natuurlijk ook mijn eerste gedacht, maar dat lijkt mij een zeer omslachtige methode (of niet :? )

I must not fear. Fear is the mind-killer. Fear is the little-death that brings total obliteration. I will face my fear. I will permit it to pass over me and through me. Where the fear has gone there will be nothing. Only I will remain.


  • wasigh
  • Registratie: Januari 2001
  • Niet online

wasigh

wasigh.blogspot.com

Je kunt een object alleen versturen als ze aan beide zijden bekend zijn, Je kunt ze oversturen met ObjectStreams en je moet ze de interface Serializable laten implementeren.

  • whoami
  • Registratie: December 2000
  • Laatst online: 23:04
Feyd-Rautha schreef op 21 augustus 2002 @ 15:47:
Dat was natuurlijk ook mijn eerste gedacht, maar dat lijkt mij een zeer omslachtige methode (of niet :? )


Hoezo?
* whoami is geen java-kenner, laat staan javahova....

Maar je hoeft toch maar enkele lijntjes toe te voegen:

In de Server.Java:

code:
1
2
3
import  User;
import Connection;
bla


en in de Client.Java hetzelfde...
toch? :?

Of zit ik er nu helemaal naast?

https://fgheysels.github.io/


  • Feyd-Rautha
  • Registratie: November 2001
  • Laatst online: 02-08-2025
ik dacht het niet

die import ... wil zeggen: packages includen, geen classes.

ter verduidelijking: mijn server-gedeelte bestaat uit 1 package en mijn client-gedeelte ook uit 1 package.

Ik kan nu natuurlijk wel een 'import Chatsrvr.*; ' in mijn Client-programma. Maar de machine waarop mijn client geinstalleerd zou worden, zal de package "Chatsrvr" niet kennen natuurlijk.

I must not fear. Fear is the mind-killer. Fear is the little-death that brings total obliteration. I will face my fear. I will permit it to pass over me and through me. Where the fear has gone there will be nothing. Only I will remain.


  • whoami
  • Registratie: December 2000
  • Laatst online: 23:04
En als je nu eens ipv 2 packages 3 packages maakt?

Een package voor de server, een voor de client en een voor de classes die je in beide nodig hebt?

* whoami behandelt de vragen van zijn eigen kloon (althans volgens sommigen). :+

https://fgheysels.github.io/


  • wasigh
  • Registratie: Januari 2001
  • Niet online

wasigh

wasigh.blogspot.com

Feyd-Rautha schreef op 21 augustus 2002 @ 15:54:
ik dacht het niet

die import ... wil zeggen: packages includen, geen classes.

ter verduidelijking: mijn server-gedeelte bestaat uit 1 package en mijn client-gedeelte ook uit 1 package.

Ik kan nu natuurlijk wel een 'import Chatsrvr.*; ' in mijn Client-programma. Maar de machine waarop mijn client geinstalleerd zou worden, zal de package "Chatsrvr" niet kennen natuurlijk.
Leg die natuurlijk eens uit?

Je kunt die classes toch gewoon meegeven aan de clients?
Om een object over te sturen moeten beide JVM's de toegang hebben tot de .class bestanden anders is het absoluut niet mogelijk om een object over te sturen (echt niet ;) ) en zo vervelend is het niet om te zorgen dat je client ook de beschikking heeft over de class. En je kunt ook een class includen hoor :)

edit:
Package namen horen eigenlijk bij conventie niet met een hoofdletter te beginnen ;)

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

Je kan toch ook
import Chatsrvr.Message;
import Chatsrvr.User;
doen...

Je hoeft echt niet perse de complete package te importeren ;)

Verwijderd

het is ook niet echt noozakelijk dat ze de .class file hebben, je kan deze .java file meegeven en dan realtime nog compileren met de class Compiler, das wel een omwegje, maar het werkt wel, en zodoende heb je de .class file nog nie nodig

  • Glimi
  • Registratie: Augustus 2000
  • Niet online

Glimi

Designer Drugs

(overleden)
Verwijderd schreef op 21 augustus 2002 @ 17:33:
het is ook niet echt noozakelijk dat ze de .class file hebben, je kan deze .java file meegeven en dan realtime nog compileren met de class Compiler, das wel een omwegje, maar het werkt wel, en zodoende heb je de .class file nog nie nodig
En wat is daar nou precies het nut van, behalve dat je app bagger traag gaat worden?

  • Apie!
  • Registratie: Januari 2000
  • Laatst online: 09-03 19:55

Apie!

Newer, better & confusinger

Er is niks mis met allebei de Projecten je class Message e.d. te laten gebruiken. Ik heb 2 jaar terug ook iets dergelijks geschreven (nog in notepad.exe :) ) Dat was een icq-achtig iets, maar dan text-based, met idd een server die verschillende clients bijhield etc etc en die server had deels dezelfde classes als de client.

Destijds had ik nog niet helemaal door hoe je packages e.d. kon gebruiken en had een aparte dir voor de server en een aparte dir voor de client en in allebei de dirs de gedeelde classes haha nu ik er aan terugdenk lol dat was niet echt beheerbaar op die manier, maar het werkte wel :+

maar ik zou idd alle gedeelde classes in een aparte package stoppen, en de server en client ook weer ieder in een eigen package
nl.gelderland.arnhem.server;
nl.gelderland.arnhem.client;
nl.gelderland.arnhem.shared;

My lungs taste the air of Time
Blown past falling sands


  • Feyd-Rautha
  • Registratie: November 2001
  • Laatst online: 02-08-2025
jup, dat heb ik nu ook gedaan:

package client
package server
package shared

Ik heb wel zitten zweten bij het opdelen in packages. Zowel 'server' als 'client' konden de package 'shared' niet vinden. Maar nu lukt het wel.

'k Heb ook mijn volledige analyse :P herbeken en hermaakt.

Mijn Server-gedeelde zal 3 threads bevatten en 2 Vectors. Namelijk:
Thread ConnectionListener
deze luistert steeds of er nieuwe users willen connecten. Er wordt een nieuwe User aangemaakt en in de UserPool (vector) toegevoegd. Ook wordt een Message ACK aangemaakt die dan in de MessagePool (vector)zal terechtkomen.

Thread MessageSender
Deze thread zal de MessagePool steeds overlopen en alle messages analyseren en naar de desbetreffende user zenden (bron- en doeluser zitten in het Message-object opgeslagen)
De verstuurde Message wordt verwijderd

Thread MessageListener
Hij zal alle inkomende berichten analyseren op 'soort' (DISCONNECT, ...) en de bijhorende actie maken (User verwijderen - toevoegen aan MessagePool - ... )


Ik vind vanmijzelf dat dat een redelijk goede analyse is en een mooi concept. Als jullie er iets anders van denken, gelieve het mij te zeggen ofzo zodat ik het kan verbeteren.

Mijn Client-gedeelte is nog bijlange niet af. Maar dat zal ook zweten zijn :)


Ik zie nu opeens dat heel toevallig mijn package-namen dezelfde zijn als mijn bovenbuur :+

I must not fear. Fear is the mind-killer. Fear is the little-death that brings total obliteration. I will face my fear. I will permit it to pass over me and through me. Where the fear has gone there will be nothing. Only I will remain.


  • Bobco
  • Registratie: Januari 2001
  • Laatst online: 30-10-2023

Bobco

I used to dream about Verona.

Feyd-Rautha schreef op 22 augustus 2002 @ 13:39:
Mijn Server-gedeelde zal 3 threads bevatten en 2 Vectors. Namelijk:
Thread ConnectionListener
deze luistert steeds of er nieuwe users willen connecten. Er wordt een nieuwe User aangemaakt en in de UserPool (vector) toegevoegd. Ook wordt een Message ACK aangemaakt die dan in de MessagePool (vector)zal terechtkomen.

Thread MessageSender
Deze thread zal de MessagePool steeds overlopen en alle messages analyseren en naar de desbetreffende user zenden (bron- en doeluser zitten in het Message-object opgeslagen)
De verstuurde Message wordt verwijderd

Thread MessageListener
Hij zal alle inkomende berichten analyseren op 'soort' (DISCONNECT, ...) en de bijhorende actie maken (User verwijderen - toevoegen aan MessagePool - ... )
Ik zie het nut van de scheiding tussen de ThreadConnectionListener en de ThreadMessageListener niet zo duidelijk. Beide zijn verantwoordelijk voor acties die worden doorgegeven door de client. In het ene geval maak je een User aan in je UserPool, in het andere geval haal je hem weg, of stop je een message in je MessagePool.

Ik zou denk ik liever een onderscheid maken in 'management' acties zoals in- en uitloggen en het echte versturen van berichten van users onderling. Je kunt dan bijvoorbeeld je client in het ene geval een commando object laten sturen en in het andere geval een message object. Deze vang je op met een listener en afhankelijk van wat voor type het is stuur je het object door naar een class die de verder afhandeling doet.

Je hebt dan ook meteen een betere scheiding tussen classes die de communicatie doen en classes die het 'echte' werk uitvoeren.

With the light in our eyes, it's hard to see.


  • Feyd-Rautha
  • Registratie: November 2001
  • Laatst online: 02-08-2025
Dus jij bedoeld een listener maken voor alle berichten (ACTIES en MESSAGES).

Die listener alle berichten laten analyseren en ACTIES naar een ActieHandler sturen en MESSAGES naar een MessageHandler sturen?

Ja, misschien zou ik wel mijn ConnectionListener en MessageLIstener kunnen integreren in 1 listener.
Maar mijn Messages hebben wel een veld waarin de soort staat (USERLIST, ACK, ...).

ps: wat bedoel je met 'echte' werk? :?

I must not fear. Fear is the mind-killer. Fear is the little-death that brings total obliteration. I will face my fear. I will permit it to pass over me and through me. Where the fear has gone there will be nothing. Only I will remain.


  • Bobco
  • Registratie: Januari 2001
  • Laatst online: 30-10-2023

Bobco

I used to dream about Verona.

Feyd-Rautha schreef op 22 augustus 2002 @ 14:58:
Maar mijn Messages hebben wel een veld waarin de soort staat (USERLIST, ACK, ...).
Je maakt waarschijnlijk gebruik van een bepaalde port om te luisteren naar binnenkomende requests op je server? Daar is er over het algemeen maar 1 van op een bepaalde machine en daarom lijkt het mij zinniger om dan ook 1 class te definieren die daar op luistert en actie neemt als er iets binnenkomt.

Verder denk ik dat je echt onderscheid moet maken in 'administratieve' requests en 'echte' messages die worden verstuurd. Beide zijn uiteraard boodschappen die verstuurd worden, maar in het ene geval wil de gebruiker iets vragen aan de server (USERLIST bv), en in het andere geval moet de server kijken voor wie de message bedoeld is. Je zou iets kunnen doen met een Message interface die de basis functionaliteit beschrijft en CommandMessage en UserMessage classes die deze implementeren. Je Listener kan dan eenvoudig met instanceof bepalen wat voor ding het is en het object doorgeven aan een handler die de rest van het werk doet.

Overigens is het misschien een goed idee om je gebruikers ook in staat te stellen een message naar een lijst van ontvangers te sturen dus die toUser niet een User te laten zijn maar een lijst van Users.
ps: wat bedoel je met 'echte' werk? Het versturen van tekst? Is dit dan geen communicatie?
Versturen en ontvangen is alleen maar de communicatie. Natuurljk is dat een heel belangrijk deel, maar de echt slimme dingen gebeuren in de rest van je applicatie, toch?

Over het algemeen is het handig om classes zo 'dom' mogelijk te houden en ze verantwoordelijk te maken voor 1 bepaalde taak.

With the light in our eyes, it's hard to see.


  • Feyd-Rautha
  • Registratie: November 2001
  • Laatst online: 02-08-2025
Dat van die messages kan ik nog herzien.

Maar idd, er is maar 1 class die op de poort luistert, nl: ConnectionListener. Als een connection is gevonden, wordt daaruit een socket gemaakt. Het versturen van berichten gebeurt dan via deze socket.

Misschien kan ik dat ook nog veranderen, maar eerst probeer ik de basis. Daarna kan ik alles nog herzien en herschrijven. :)

Toch bedankt voor de tips

I must not fear. Fear is the mind-killer. Fear is the little-death that brings total obliteration. I will face my fear. I will permit it to pass over me and through me. Where the fear has gone there will be nothing. Only I will remain.


  • Kapoen
  • Registratie: Mei 2002
  • Laatst online: 01-09 15:09
en als je nu es het te delen object gewoon aanbied via RMI?

Clowns to the left of me, Jokers to the right


  • Feyd-Rautha
  • Registratie: November 2001
  • Laatst online: 02-08-2025
Wat is RMI :?

* Feyd-Rautha is nog maar een beginneling JAVA-progger hoor ... :)

I must not fear. Fear is the mind-killer. Fear is the little-death that brings total obliteration. I will face my fear. I will permit it to pass over me and through me. Where the fear has gone there will be nothing. Only I will remain.


  • Bobco
  • Registratie: Januari 2001
  • Laatst online: 30-10-2023

Bobco

I used to dream about Verona.

Feyd-Rautha schreef op 26 augustus 2002 @ 10:50:
Wat is RMI :?

* Feyd-Rautha is nog maar een beginneling JAVA-progger hoor ... :)
RMI staat voor Remote Method Invocation. Simpel gezegd is het een manier om methods aan te roepen op objecten die in een andere JVM draaien. Op de Java site van Sun is een prima tutorial te vinden. Succes!

With the light in our eyes, it's hard to see.


  • wasigh
  • Registratie: Januari 2001
  • Niet online

wasigh

wasigh.blogspot.com

Bobco schreef op 26 augustus 2002 @ 10:53:
[...]


RMI staat voor Remote Method Invocation. Simpel gezegd is het een manier om methods aan te roepen op objecten die in een andere JVM draaien. Op de Java site van Sun is een prima tutorial te vinden. Succes!
Lekkere vent ;)

Meneer begint net met Java en jij wil hem al aan de IDL, LDAP, studs en skeletons en zooi.. :P Waarom niet meteen session beans ;)

  • Bobco
  • Registratie: Januari 2001
  • Laatst online: 30-10-2023

Bobco

I used to dream about Verona.

Dank je, al hoor ik dat liever van mijn vriendin ;)
Meneer begint net met Java en jij wil hem al aan de IDL, LDAP, studs en skeletons en zooi.. :P Waarom niet meteen session beans ;)
Mja, ik denk dat het beter is om de TS goede informatie te geven dan maar niets te zeggen. Als iemand nieuwsgierig is naar een bepaald onderwerp moet hij/zij zelf bepalen of het _te_ moeilijk is of niet.

Ik vind het lastig om uit een paar posts te destilleren of iemand wel of niet aan dit soort dingen toe is. Op het moment dat je gaat knoeien met sockets ben je, denk ik, ook wel toe aan RMI. En zo vreselijk moeilijk is het nou ook weer niet, zeker niet als je alleen maar een paar classes remote hoeft te hebben.

Overigens breng je wel een belangrijk punt naar voren: wat is er nu moeilijk en wat niet? RMI, of gedistribueerde systemen in het algemeen, zijn per definitie lastiger dan non-gedistribueerde systemen. Je ontkomt er niet aan dat je eerst door wat uitleg heen moet voordat je het kunt toepassen.

De tutorial waar ik naar verwees begint in ieder geval simpel, met een voorbeeldje dat duidelijk maakt welke class waar moet draaien, wat er in de interface definitie moet staan en hoe je de hele zaak aan de praat moet krijgen.

Volgende onderwerp: session beans in een geclusterde applicatieserver omgeving! ;)

With the light in our eyes, it's hard to see.

Pagina: 1