Toon posts:

Java RMI, clients inlichten na wijziging op server

Pagina: 1
Acties:

Verwijderd

Topicstarter
Ik ben een blackjack applicatie aan het ontwikkelen die via het netwerk te spelen is (RMI client server verbinding).

Het probleem is dat wanneer een speler een kaart neemt, deze op bij alle clients in de gui weergegeven moet worden. Ik dacht dit te doen door de server PropertyChangeSupport te geven en de clients de interface PropertyChangeListeners te laten implementeren en zo via de interface te koppelen aan de server. Ik krijg het niet voor elkaar om de clients toe te voegen aan de client met addPropertyChangeListener...(Geeft nullpointer exception). Kan ik op deze manier wel verbinding krijgen, en uiteindelijk een firePropertyEvent sturen die door alle clients ontvangen wordt, of is er een andere (makkelijker) manier om dit te doen?

  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
sensei1: Ik ben een blackjack applicatie aan het ontwikkelen die via het netwerk te spelen is (RMI client server verbinding).
Leuk :) .
Het probleem is dat wanneer een speler een kaart neemt, deze op bij alle clients in de gui weergegeven moet worden.
Dat kan... maar merk op dat de client dan in feite ook 'server' moet gaan spelen.

De klasse property-change-listener moet uitgebreid worden zodat hij remote-exceptions gaan gooien. Je kunt daarom beter even een eigen listener-interface maken die extend van Remote. Verder moet je voor die klassen ook stubs genereren: deze moeten getransporteerd worden naar de server.

Merk op dat het object wat meldingen binnen krijgt dus niet geserializateerd mag worden! Dit object wordt dan immers verhuisd naar de server. Je bent dan nog geen stap verder gekomen richting de client ;) .

Heb je hier allemaal rekening mee gehouden?

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


Verwijderd

Topicstarter
Euhm, dat klinkt allemaal erg ingewikkeld. :?
Er moet toch ook een makkelijke manier zijn waarmee je alle clients op de hoogte kunt stellen dat er iets veranderd is. Daarna kunnen de clients dan zelfstandig wel de data ophalen bij de server, ik kan de clients wel periodiek laten kijken of er iets veranderd is op de server, maar dat vind ik geen "nette" oplossing...

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 11-09 08:26

.oisyn

Moderator Devschuur®

Demotivational Speaker

waarom maak je geen methode die de client blokkert tot er wat nieuws te vertellen is?

de client roept dan in een loopje steeds die methode aan, en behandeld het teruggegeven object waar de info in staat wat er is gebeurd

zeg maar zo (in halve pseudo code):
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
while (aanHetSpelen)
{
    NieuwsObject o = server.getNieuws ();
    switch (o.nieuws)
    {
      case JOUW_BEURT:
        keuze = vraagOmKeuze ();
        server.maakKeuze (keuze);
        break;

      case NIEUWE_KAART:
        toonKaart (o.kaart, o.speler);
        break;

      case SPEL_BEEINDIGD:
        aanHetSpelen = false;
        break;
    }
}

nu hoeft de client geen server te zijn, en de bedoeling van de server is om pas een nieuw NieuwsObject terug te geven als er daadwerkelijk wat te vertellen is, anders moet ie gewoon wachten (vereist wel dat je met meerdere threads moet werken natuurlijk)

't is maar een ideetje :)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
sensei1: Euhm, dat klinkt allemaal erg ingewikkeld. :?
en dan te bedenken dat RMI relatief nog erg gemakkelijk is ;) .

Ik zal het even duidelijker proberenuitleggen: je maakt nu al op de server object(en) remote beschikbaar. De clients vragen een referentie (stub genoemd) op naar dit object. Het object zelf blijft op de server draaien. Methode aanroepen op de client op dit object worden doorgegeven naar de server.

In dit geval wordt dus alle communicatie gestart door de client.

Je wilt nu in feite iets anders: zonder dat de client iets doet wil je gaan communiceren. Deze communicatie wordt gestart door de server. De server heeft nu een verwijzing nodig naar een object op de client. Dit object moet je aanmelden bij de server en dit moet een remote object zijn zoals je nu ook al op de server hebt. De client kan nu aangeroepen worden vanuit de server.
Er moet toch ook een makkelijke manier zijn waarmee je alle clients op de hoogte kunt stellen dat er iets veranderd is.
Tja, het kan toch echt niet makkelijker, maar het is ook niet zo moeilijk als het wellicht klinkt. Je moet bedenken dat de server een manier moet hebben om de client aan te spreken. Dat kan alleen als de server een verwijzing heeft naar een remote object op de client...
ik kan de clients wel periodiek laten kijken of er iets veranderd is op de server, maar dat vind ik geen "nette" oplossing...
Zeker, dat is niet fraai :) .

Misschien ken je het Observer pattern? Probeer anders als oefening eens een gedistribueerde implementatie hiervan te maken. Op de server, die Observable is, kan je dan RemoteObservers aanmelden. Je kunt zo goed bekijken hoe het in elkaar zit zonder dat je gelijk het probleem moet oplossen in jouw applicatie met allemaal zaken de afleiden :) .

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
OiSyN: waarom maak je geen methode die de client blokkert tot er wat nieuws te vertellen is?
Hum.... das een grappige gedachte :) . Ik denk dat je echter wel snel problemen krijgt met time-outs op deze manier... Je roept immers een methode aan die voorlopig nog weleens niet terug zou kunnen keren...
't is maar een ideetje :)
Leuk idee, dat wel :) .

Helaas is de meest gebruikelijke manier toch om remote objecten op de server aan te melden :) .

Als je dat allemaal niet wilt kan je natuurlijk nog direct met sockets werken, maar ja: dan kan je net zo goed niet met RMI werken :o .

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


Verwijderd

Topicstarter
nu hoeft de client geen server te zijn, en de bedoeling van de server is om pas een nieuw NieuwsObject terug te geven als er daadwerkelijk wat te vertellen is, anders moet ie gewoon wachten (vereist wel dat je met meerdere threads moet werken natuurlijk)
Dan krijg je dus de minder nette periodieke "check the server methode" :(.

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 11-09 08:26

.oisyn

Moderator Devschuur®

Demotivational Speaker

Op donderdag 10 januari 2002 00:58 schreef sensei1 het volgende:

[..]

Dan krijg je dus de minder nette periodieke "check the server methode" :(.
nee, want hij is niet periodiek :)

maar goed, anders moet je het op mbravenboers manier doen... moet toch geen probleem zijn? (hij verwoord het misschien moeilijker dan dat het is ;))

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
sensei1: Dan krijg je dus de minder nette periodieke "check the server methode" :(.
Je checked de server wel, maar het voorstel van OiSyN was wel minder ranzig dan het zgn 'pollen': Bij OiSyN roep je een methode aan die pas terugkeerd als er iets nieuws is... Bij pollen roep je om de zoveel tijd een methode aan die direct terug keert en vertelt of er iets nieuws is.

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
OiSyN: hij verwoord het misschien moeilijker dan dat het is ;)
en ik doe nog wel zo m'n best ;) .

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 11-09 08:26

.oisyn

Moderator Devschuur®

Demotivational Speaker

mbravenboer: Ik denk dat je echter wel snel problemen krijgt met time-outs op deze manier... Je roept immers een methode aan die voorlopig nog weleens niet terug zou kunnen keren...
ja daar zat ik dus ook aan te denken, maar ik heb eigenlijk geen idee hoe dat geregeld is... ik bedoel, je kunt toch wel een functie aanroepen die gewoon ergens lang over doet? Dat moet toch wel gewoon ondersteund worden lijkt me? Of moet je het dan op de manier doen zoals jij aan de topicstarter vertelde, dus dat als je een functie hebt die er mogelijk lang over kan doen dat je dan een methode implementeerd dat de server de client op de hoogte stelt als ie klaar is

.edit: btw, ik had hier vanmiddag een tentamen over :D (rmi, activation, applet signing, corba, bla bla bla :))

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Verwijderd

Topicstarter
de client roept dan in een loopje steeds die methode aan, en behandeld het teruggegeven object waar de info in staat wat er is gebeurd
Als ik het goed begrijp roep je toch steeds remote een methode aan, alleen geeft deze pas wat terug als er daadwerkelijk wat veranderd is?

  • ronaldmathies
  • Registratie: Juni 2001
  • Niet online
Op donderdag 10 januari 2002 01:04 schreef OiSyN het volgende:

[..]

ja daar zat ik dus ook aan te denken, maar ik heb eigenlijk geen idee hoe dat geregeld is... ik bedoel, je kunt toch wel een functie aanroepen die gewoon ergens lang over doet? Dat moet toch wel gewoon ondersteund worden lijkt me? Of moet je het dan op de manier doen zoals jij aan de topicstarter vertelde, dus dat als je een functie hebt die er mogelijk lang over kan doen dat je dan een methode implementeerd dat de server de client op de hoogte stelt als ie klaar is

.edit: btw, ik had hier vanmiddag een tentamen over :D (rmi, activation, applet signing, corba, bla bla bla :))
Je zou natuurlijk je "server" in een andere thread kunnen draaien, dan heb je geen last van timeouts maar je server wacht gewoon op een ooit inkomend bericht.

3015 Wp-z 5360 Wp-nno op 2 x SMA-SB3600 TL-21, Warmtepomp: ERSC-VM2CR2 / PUHZ-SHW140 YHA, WTW Q350, EV Kia Ev6 GT-Line


  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
OiSyN: ja daar zat ik dus ook aan te denken, maar ik heb eigenlijk geen idee hoe dat geregeld is... ik bedoel, je kunt toch wel een functie aanroepen die gewoon ergens lang over doet?
Hum ja... maar je zou zeggen dat er toch wel ooit een time-out moet komen... Ik weet niet precies hoe dat gedefinieerd is eigenlijk :o .
Of moet je het dan op de manier doen zoals jij aan de topicstarter vertelde, dus dat als je een functie hebt die er mogelijk lang over kan doen dat je dan een methode implementeerd dat de server de client op de hoogte stelt als ie klaar is
Dat wordt ook wel een callback genoemd (die ken je wel van corba vermoed ik ;) )... Dit is denk ik sowieso wel de nettere methode...
ik had hier vanmiddag een tentamen over :D (rmi, activation, applet signing, corba, bla bla bla :))
Hehe :) . Leuk onderwerp wel he? :) .

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 11-09 08:26

.oisyn

Moderator Devschuur®

Demotivational Speaker

Op donderdag 10 januari 2002 01:08 schreef ronaldmathies het volgende:

[..]

Je zou natuurlijk je "server" in een andere thread kunnen draaien, dan heb je geen last van timeouts maar je server wacht gewoon op een ooit inkomend bericht.
nee wij doelden op timeouts van de client kant

1. client roept methode aan op server, en wacht op antwoord
2. server doet er vervolgens heel lang over om dat antwoord te geven
3. client geeft een timeout

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 11-09 08:26

.oisyn

Moderator Devschuur®

Demotivational Speaker

Op donderdag 10 januari 2002 01:09 schreef mbravenboer het volgende:

[..]

Hum ja... maar je zou zeggen dat er toch wel ooit een time-out moet komen... Ik weet niet precies hoe dat gedefinieerd is eigenlijk :o .
in princiepe zitten timeouts verwerkt in het tcp protocol (rmi is toch tcp?). De client wacht op een terugkerende datastroom, maar de data komt maar niet. Dat is echter geen reden voor een timeout, tenzij het expliciet geimplementeerd is (zo van: if (na x seconden nog geen data binnen) throw TimeoutException :))

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Verwijderd

het kan, maar RMI is er niet voor gemaakt.
ben er zelf mee opgehouden het uit te zoeken maar check deze uit:
http://developer.java.sun.com/developer/onlineTraining/rmi/exercises/RMICallback/index.html
daar wordt het zaakje uitgelegd!

goodluck

  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
Ik lees dat er inderdaad een time-out is... Ik ben nu aan het uitzoeken hoe lang die is. Ik las ergens 5 sec, maar dat lijkt mij wel erg weinig...

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


Verwijderd

Topicstarter
nee wij doelden op timeouts van de client kant

1. client roept methode aan op server, en wacht op antwoord
2. server doet er vervolgens heel lang over om dat antwoord te geven
3. client geeft een timeout
Aaaaaah, nu snap ik het :). Er komt in ieder geval een timer bij elke client waarbinnen er gereageerd moet worden, anders duurt het spel te lang. Hoelang duurt het eigenlijk voor een thread een timeout geeft? :)

  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
sensei1: Aaaaaah, nu snap ik het :). Er komt in ieder geval een timer bij elke client waarbinnen er gereageerd moet worden, anders duurt het spel te lang. Hoelang duurt het eigenlijk voor een thread een timeout geeft? :)
De method-call zal waarschijnlijk in seconden een time out geven. Ik zie hier waarden van 5, 15 en 30 dus het is mij niet helemaal duidelijk wat het nu precies is. Wellicht dat je het zelfs kunt configureren.

Ik zou je echter willen aanraden om het gewoon netjes met callbacks te doen. Het kan geen kwaad om je even goed in de principes van RMI te verdiepen :) .

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


Verwijderd

Topicstarter
Ik zou je echter willen aanraden om het gewoon netjes met callbacks te doen. Het kan geen kwaad om je even goed in de principes van RMI te verdiepen :) .
Heb je helemaal gelijk in, ga me maar eens in de callbacks verdiepen, met dat voorbeeld van morrox moet ik al een eind kunnen komen.

  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
Ik heb trouwens nog wel een voorbeeld liggen wat ik ff snel kan herschrijven. Zal het zo even posten :) .

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • The - DDD
  • Registratie: Januari 2000
  • Laatst online: 03-09 16:40
Hallo.... Ik zeg MultiCast socket...

1 pakketje het netwerk op en alle luisternde (!) client's zijn weer bij de tijd.

ftp://ftp.javasoft.com/docs/tut-bingo.zip
http://java.sun.com/docs/books/tutorial/download/tut-bingo.zip

De een is FTP download en de ander is HTTP download. Het is DE Sun Bingo demo.. :P Een Bingo game geimplementeerd met Java.


Hoe werkt een multicast. Heel simpel. Een client luisterd naar een bepaalde multicast groep. Zo lang je op hetzelfde subnet zit: geen probleem. Zodra er routers tussen zitten: Check de router specs en instellingen.

Hoe het werkt: Er wordt een UDP bericht verstuurd. Juist geen TCP maar UDP, dat is dus connectieloos. Komt het niet aan, dan weet de server het niet. Echter binnen 1 subnet komt het altijd aan of er is echt een hardware fout en TCP zou ook niet aan zijn gekomen.

  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
The - DDD: Hallo.... Ik zeg MultiCast socket...
Kan, maar als de rest van de applicatie met RMI werkt is het net zo netjes (en makkelijk) om ook dit met RMI te doen... Om dan met sockets te gaan werken is een beetje low-level misschien :) .

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
Ik heb een voorbeeld gebakken :) .

Allereerst moet je natuurlijk een interface voor een server hebben. Deze is heel simpel:
code:
1
2
3
4
5
6
7
import java.rmi.Remote;
import java.rmi.RemoteException;

public interface Server extends Remote
{
    public void addListener(Listener listener) throws RemoteException;
}

Je kunt dus alleen maar Listeners aanmelden.

Deze listeners zien er als volgt uit:
code:
1
2
3
4
5
6
7
import java.rmi.Remote;
import java.rmi.RemoteException;

public interface Listener extends Remote
{
    public void sendMessage(String message) throws RemoteException;
}

.
Ook simpel dus :) .

Nu maken we een implementatie van de server. Deze is ietsje groter.
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayList;
import java.util.List;
import java.util.Iterator;

public class ServerImpl extends UnicastRemoteObject implements Server
{
    private List listeners;

    public ServerImpl() throws RemoteException
    {
      super();
      listeners = new ArrayList();
    }

    public void addListener(Listener listener) throws RemoteException
    {
      synchronized(listeners)
      {
        listeners.add(listener);
      }
    }

    public void sendMessage(String message)
    {
      synchronized(listeners)
      {
        Iterator iterator = listeners.iterator();

        while(iterator.hasNext())
        {
            Listener listener = (Listener) iterator.next();

            try
            {
              listener.sendMessage(message);
            }
            catch(Exception exc)
            {
            }
        }
      }
    }
}

De code spreekt voor zich denk ik. Super makkelijk :) .

Nu maken we een simpele ListenerImpl:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

public class ListenerImpl extends UnicastRemoteObject implements Listener
{
    public ListenerImpl() throws RemoteException
    {
      super();
    }

    public void sendMessage(String message) throws RemoteException
    {
      System.out.println("Incoming message: " + message);
    }
}

Je moet de ListenerImpl en de ServerImpl even door rmic heenhalen:
rmic ListenerImpl
rmic ServerImpl
Dan worden er stubs gegeneerd voor deze remote objecten.

Nu nog even een simpele client applicatie die je kan starten:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import java.rmi.Naming;
import java.rmi.registry.Registry;

public class ClientApplication
{
    public static void main(String[] ps)
    {
      try
      {
          Server server = (Server) Naming.lookup(getNamingURL());
        server.addListener(new ListenerImpl());
      }
      catch(Exception exc)
      {
        exc.printStackTrace();
      }
    }

    private static String getNamingURL()
    {
        return "//localhost:" + Registry.REGISTRY_PORT +"/pandoramix/rmi-server";
    }
}

Uiteraard moet de server ook gestart kunnen worden en moet er nog iets verzonden worden ;) . De server moet je starten voor de clients.
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import java.rmi.Naming;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

public class ServerApplication
{
    public static void main(String[] ps)
    {
      try
      {
            LocateRegistry.createRegistry(Registry.REGISTRY_PORT);

          ServerImpl server = new ServerImpl();

            Naming.rebind(getNamingURL(), server);

        while(true)
        {
            Thread.currentThread().sleep(5000);
            server.sendMessage("Hey, the time is: " + System.currentTimeMillis());
        }
      }
      catch(Exception exc)
      {
        exc.printStackTrace();
      }
    }

    private static String getNamingURL()
    {
        return "//localhost:" + Registry.REGISTRY_PORT +"/pandoramix/rmi-server";
    }
}

Ok. Je kunt het zaakje dus draaien door even te compileren, rmic eroverheen te halen en een ServerApplication te starten. Daarna kan je meerdere ClientApplications starten en de communicatie werkt perfect :)

Viel best mee he? :) .

Je kind in de Listener zelf methoden opnemen voor verschillende meldingen die je wilt doen. Uiteraard moet je in een echte applicatie ook even netter rekening houden met het afmelden van listeners op de server :) .

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • The - DDD
  • Registratie: Januari 2000
  • Laatst online: 03-09 16:40
Ok, voorbeelden you want? Hier is een Multicast server + socket. Als je hem gebruikt, draaien in een aparte thread.

De multicast sender, (stuurt de pakketjes):

Aan te roepen met java MulticastSender all-systems.mcast.net 4000
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
import java.net.*;
import java.io.*;


public class MulticastSender {

  public static void main(String[] args) {
  
    InetAddress ia = null;
    int port = 0;
    byte ttl = (byte) 1;
  
    // read the address from the command line
    try {
    ia = InetAddress.getByName(args[0]);
    port = Integer.parseInt(args[1]);
    if (args.length > 2) ttl = (byte) Integer.parseInt(args[2]);
    }
    catch (Exception e)  {
    System.err.println(e);
    System.err.println(
     "Usage: java MulticastSender multicast_address port ttl");
    System.exit(1);
    }
  
    byte[] data = "Here's some multicast data\r\n".getBytes();
    DatagramPacket dp = new DatagramPacket(data, data.length, ia, port);
  
    try {
    MulticastSocket ms = new MulticastSocket();
    for (int i = 1; i < 10; i++) {
      ms.send(dp, ttl);
    }
    ms.close();
    }
    catch (SocketException se) {
    System.err.println(se);
    }
    catch (IOException ie) {
    System.err.println(ie);
    }  
  
  }

}

Het nu volgende geval snuffelt aan een multicast socket, en print de inhoud van de pakketjes. Je geeft het IP en poort nummer gescheiden door een spatie op.

Aan te roepen met: java MulticastSniffer all-systems.mcast.net 4000
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
import java.net.*;
import java.io.*;

public class MulticastSniffer {

  public static void main(String[] args) {
  
    InetAddress group = null;
    int port = 0;
  
    // read the address from the command line
    try {
    group = InetAddress.getByName(args[0]);
    port = Integer.parseInt(args[1]);
    }  // end try
    catch (Exception e) {
    // ArrayIndexOutOfBoundsException, NumberFormatException,
    // or UnknownHostException
    System.err.println(
     "Usage: java MulticastSniffer multicast_address port");
    System.exit(1);
    }
  
    MulticastSocket ms = null;
  
    try {
    ms = new MulticastSocket(port);
    ms.joinGroup(group);
    
    byte[] buffer = new byte[8192];
    while (true) {
      DatagramPacket dp = new DatagramPacket(buffer, buffer.length);
      ms.receive(dp);
      String s = new String(dp.getData());
      System.out.println(s);
    }
    }
    catch (IOException e) {
    System.err.println(e);
    }
    finally {
    if (ms != null) {
      try {
        ms.leaveGroup(group);
        ms.close();
      }
      catch (IOException e) {} 
    }
    } 
  
  }

}

all-systems.mcast.net resolved naar het lokale multicast adres 124.0.0.1 . Dit ip wordt NOOIT door een router door gegeven. Alle multicast pakketen blijven dus op het subnet van oorsprong. Het klinkt heel vaag, maar het maakt niet uit wat voor subnet mask je hebt. Die 124.0.0.1 werkt op hetzelfde subnet ALTIJD.

  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
Hehe :) . Wat is keuze toch reuze! ;)

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


Verwijderd

Topicstarter
Okee, ik heb nu het RMI callback gebeuren ingebouwd, werkt allemaal perfect, nu wil ik het alleen zo hebben dat een cient via een optie in het JMenu kan connecten naar de server. Zonder callback (dus client-server) werkte dit perfect. Maar nu ik de callback erin heb zitten lukt het me niet meer om dit voor elkaar te krijgen, om de een of andere reden moet de host gelijk vanuit de constructor worden aangeroepen.

Bestaat er een manier om dit te doen vanuit een JMenuItem?

ps. krijg deze error als ik dat nu probeer:
java.security.AccessControlContext: Access denied (java.net.SocketPermission)

Verwijderd

Topicstarter
niemand die weet hoe dit moet?
Loop een beetje vast hierop, vandaar dat ik hem maar even "omhoog kick"

  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
Begrijp ik het goed dat hij het wel doet als je gelijk bij het opstarten van de applicatie een connectie maakt, maar dat je een SecurityException krijgt als je pas later naar aanleiding van een aktie van de gebruiker een connectie gaat maken?

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


Verwijderd

Topicstarter
Hij doet het inderdaad wel als ik de methode connect vanuit de constructor vanuit de class zelf aanroep, maar niet als ik dit doe door vanuit een andere class (frame) de methode client.connect() aan te roepen. Dan krijg ik die error te zien

  • MisterData
  • Registratie: September 2001
  • Laatst online: 07-09 20:23
Of kijk eens naar het Bingo voorbeeldje van Sun, die hebben met RMI een mooi bingospel gemaakt die ook zoiets doet geloof ik :) Te vinden op http://java.sun.com :)

  • The - DDD
  • Registratie: Januari 2000
  • Laatst online: 03-09 16:40
Op dinsdag 15 januari 2002 16:54 schreef MisterData het volgende:
Of kijk eens naar het Bingo voorbeeldje van Sun, die hebben met RMI een mooi bingospel gemaakt die ook zoiets doet geloof ik :) Te vinden op http://java.sun.com :)
Bij die bingo app, heb je het volgende probleem. Zodra er een balletje getrokken wordt, dan moet dit aan alle clienten verteld worden. Een vergelijkbaar iets als bij de hier te bouwen black-jack game. In de Bingo demo hebben ze het op de hoogte brengen van alle clienten, gedaan middels een multicast.

Je zou elke client kunnen laten multicasten, enige nadeel is dat dat behoorlijk beslag legt op je netwerk. Weten jullie waarom systeembeheerders zo pissed worden wanneer je Quake 1 draait? omdat dit werkt middels multicasten. En dat kan een heel netwerk plat leggen als je dat met een mannetje of 10-15 doet. Ligt er natuurlijk aan hoe vaak je een multicast doet.

  • MisterData
  • Registratie: September 2001
  • Laatst online: 07-09 20:23
Ja, en hoe zou je dat dan anders willen doen ?

  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
sensei1: Hij doet het inderdaad wel als ik de methode connect vanuit de constructor vanuit de class zelf aanroep, maar niet als ik dit doe door vanuit een andere class (frame) de methode client.connect() aan te roepen. Dan krijg ik die error te zien
Hum, ik begrijp echt niet waarom de locatie van het maken van de connectie hier security problemen oplevert. Je zou zeggen dat dit absoluut niet zou mogen uitmaken. Wellicht dat het te maken heeft met instellen van de RMISecurityManager? Maar dan nog snap ik niet waarom hij het in een vroeger stadium wel doet en later niet.... Ik ben dit probleem zelf in ieder geval nog nooit tegen gekomen. Misschien dat je compact wat code kan posten waar het mis gaat zodat we wat kunnen testen?

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


Verwijderd

We zijn hier ook bezig met het maken van een eigen online
kaartspelletje, en hebben het voorbeeld bestudeerd en (gedeeltelijk)
geimplementeerd. Echter, we hebben een toch wel groot probleem: Onze
server draait op een pc, en de client wordt gestart op een andere pc. De
client maakt connectie met de server via internet. De client wordt
gestart via een lokaal netwerk, de internetverbinding zit op een andere
pc binnen het netwerk.

Het hele gedoe met het 'rebinden' op de server en het 'lookuppen' op de
client gaat allemaal goed. We kunnen verbinding maken met de server, en
de client kan vervolgens via de server-interface methoden aanroepen en
krijgt eventuele returnvalues terug via deze interface. Allemaal leuk en
aardig, maar aangezien het ook de bedoeling is, dat er dingen door de
server naar alle (of een aantal) clients kan sturen, zonder dat de
client hiervoor een request heeft gedaan (server 'pusht' naar de client
dus), moet de server ook een referentie van de client hebben. Hiervoor
zegt het voorbeeld: een ListenerImpl creëren en deze meegeven , zodat
deze kan worden opgeslagen op de server. Aan de hand van die listener
kan de server de client weer bereiken als hij iets wil pushen. Maar op
het moment dat de ListenerImpl op de client-kant wordt aangemaakt, dan
wordt er een verkeerd IP adres eraan gekoppeld. De client geeft zijn
lokale IP adres mee, en verstuurt vervolgens die ListenerImpl naar de
server. Als de server dan iets via die listener wil pushen, dan probeert
hij dit naar het meegegeven IP adres te sturen. Maar omdat hier het
lokale IP adres van de client staat, en niet het internet IP adres, zal
de server de client nooit kunnen bereiken.

De vraag is: hoe kan de client het juiste IP adres koppelen aan de
ListenerImpl, zodat de server de client later weer kan opzoeken wanneer
deze info wil pushen naar de client?

Verwijderd

Topicstarter
Op woensdag 06 maart 2002 14:16 schreef RudeDog het volgende:

Hiervoor
Maar op
het moment dat de ListenerImpl op de client-kant wordt aangemaakt, dan
wordt er een verkeerd IP adres eraan gekoppeld. De client geeft zijn
lokale IP adres mee, en verstuurt vervolgens die ListenerImpl naar de
server.
dus jij geeft als argument aan de methode addListener het ip adres mee?

Ik snap het denk ik niet helemaal, want de connectie van de client naar de server lukt al wel? als de client iets opvraagt bij de server dan krijg je wel iets terug. De listenerImpl bevat toch niets anders dan bijvoorbeeld de methode notifyAll(String message)

Verwijderd

Op woensdag 06 maart 2002 18:59 schreef sensei1 het volgende:

[..]

dus jij geeft als argument aan de methode addListener het ip adres mee?

Ik snap het denk ik niet helemaal, want de connectie van de client naar de server lukt al wel? als de client iets opvraagt bij de server dan krijg je wel iets terug. De listenerImpl bevat toch niets anders dan bijvoorbeeld de methode notifyAll(String message)
Nee, wat we eigenlijk doen op de client (net als in het voorbeeld) is:
code:
1
2
3
ServerInterface inter = (ServerInterface)Naming.lookup(blablabla)
ListenerImpl li = new ListenerImpl();
inter.addListener(li);

De 'inter' is de referentie naar de server zeg maar.
Met de ListenerImpl die aangemaakt is op de client, sturen we zeg maar de referentie van de client op naar de server, zodat de server op zijn beurt via die referentie de client weer kan vinden voor het 'pushen' van info naar (alle) clients.

Maar bij het maken van die ListenerImpl wordt automatisch het lokale IP adres eraan gekoppeld. Maar dan kan de server de client nooit meer vinden als je via internet connect, aangezien de server dmv de meegegeven Listener(interface) info naar de clients kan 'pushen'.

Hopelijk is het nu ietsjes duidelijker? :)

RudeDog

Verwijderd

Hmmmm, interesant ... ben benieuwd hoe de topicstarter dit opgelost heeft. Die lijkt hier geen probleem met te hebben (anders had die het vast wel op GOT gepost :)).

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 11-09 08:26

.oisyn

Moderator Devschuur®

Demotivational Speaker

Op dinsdag 15 januari 2002 17:11 schreef The - DDD het volgende:

[..]

Je zou elke client kunnen laten multicasten, enige nadeel is dat dat behoorlijk beslag legt op je netwerk. Weten jullie waarom systeembeheerders zo pissed worden wanneer je Quake 1 draait? omdat dit werkt middels multicasten. En dat kan een heel netwerk plat leggen als je dat met een mannetje of 10-15 doet. Ligt er natuurlijk aan hoe vaak je een multicast doet.
beetje late reactie, maar ik lees m nu pas :)
Quake1 (en alle andere multiplayer spellen) werken echt niet met multicasting. Er is voor elke client een aparte datastroom met de server. en DAAROM worden sysbeheerders zo pissed, omdat multicasting veel efficienter werkt dan voor elke client een aparte stroom (data wordt dubbel verstuurd)

Het nadeel van multicast netwerken is alleen dat ze meestal niet verder komen dan het eigen subnet. (Hoe zit het eigenlijk met multicast adressen op het inet? Zijn die er uberhaupt wel? Lijkt me niet handig, dan moet de data het hele inet over. Broadcasten kan tenslotte ook niet)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Verwijderd

Topicstarter
Op woensdag 06 maart 2002 21:08 schreef Zpeedy het volgende:
Hmmmm, interesant ... ben benieuwd hoe de topicstarter dit opgelost heeft. Die lijkt hier geen probleem met te hebben (anders had die het vast wel op GOT gepost :)).
Ik had het probleem niet voor het werkend maken van een callback principe via inter en intra net... op het netwerk waar ik het moest implementeren zaten alleen pc's met een internet ip adres :)

Verwijderd

Topicstarter
Ben elf ook nieuwsgierig wat hier de oplossing voor is, dus heb even gezocht wat je wilt klinkt mij een beetje als rmi met ip masquerading, en het maken van een verbinding achter bijv. een firewall. Een paar links die ik tegengekomen ben en mij wel nuttig leken:
http://java.sun.com/products/jdk/rmi/archives/6607.html
http://java.sun.com/products/jdk/rmi/archives/7777.html
http://forum.java.sun.com/thread.jsp?forum=31&thread=179438
http://www.gsd.inesc.pt/tfc/gcdist/java/rmi/especif/rmi-protocol.doc.html#3477

Misschien dat RMI mulitplexing de oplossing biedt?

Verwijderd

Wij zijn multiplexing ook tegengekomen, maar er nog niet veel verder naar gekeken.

Ik zou graag willen weten of het wel mogelijk is met het voorbeeld dat mbravenboer gaf om via internet een verbinding te maken met de server en dat de server dus ook info kan pushen naar de client. Of werkt dit voorbeeld alleen binnen een lokaal netwerk?
Pagina: 1