Bonjour a tous!
Je m'arrache ce qu'il me reste de cheveux depuis deux jours suite à un problème en RMI...
Je suis en train de mettre en place un système de client/serveur, avec des callback.
J'ai donc un serveur contenant la liste des instances clientes connectées...je voudrais pouvoir lors d'un broadcast tester si mes clients sont encore présents ou non... si le client préviens le serveur de son arrêt, je peux aisement retirer le client de la liste du serveur, mais quand cet arrêt est inopiné (plantage machine, coupure réseau ou autre) je n'arrive pas à le détecter...
Voici les extraits de code concernés :
Mon interface graphique cliente instancie un ClientImpl
Au niveau du serveur :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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 package tlibrmi.client; import java.rmi.Naming; import java.rmi.RemoteException; import java.rmi.server.UnicastRemoteObject; import java.util.ArrayList; import java.util.Iterator; import tlibrmi.common.Client; import tlibrmi.common.MyRmiClientListener; import tlibrmi.common.Server; public class ClientImpl extends UnicastRemoteObject implements Client{ private static final long serialVersionUID = 1L; ArrayList listener = new ArrayList(); Server serv = null; public ClientImpl() throws RemoteException { super(); } public void initServ(String adress,String id_user) throws Exception{ try{ serv = (Server)Naming.lookup(adress); serv.connect(this, id_user); } catch(Exception e){ e.printStackTrace(); } System.out.println("init Serv done"); } public void setOrderToServer(String order, String arg) throws RemoteException{ serv.getOrderFromClient(order, arg,this); } public void getOrderFromServer(String order, String arg) throws RemoteException{ fireEvent(order, arg); } public void addListener(MyRmiClientListener mrl){ listener.add(mrl); } public void fireEvent(String order, String arg) { Iterator it = listener.iterator(); while(it.hasNext()){ MyRmiClientListener mrl = (MyRmiClientListener)it.next(); mrl.distantOrder(order, arg); } } }
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149 package tlibrmi.server; import java.rmi.RemoteException; import java.rmi.registry.LocateRegistry; import java.rmi.registry.Registry; import java.rmi.server.UnicastRemoteObject; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.Properties; import tlibrmi.common.Client; import tlibrmi.common.MyRmiServListener; import tlibrmi.common.Server; public class ServerImpl extends UnicastRemoteObject implements Server{ private static final long serialVersionUID = 1L; HashMap v_user = new HashMap(); ArrayList listener = new ArrayList(); int id_invite = 0; public ServerImpl() throws RemoteException { super(); } public void setOrderToClient(String order, String arg, Client cl) throws RemoteException{ System.out.println("-set se "+order+" "+arg); cl.getOrderFromServer(order, arg); } public void getOrderFromClient(String order, String arg, Client cl){ System.out.println("-get se "+order+" "+arg); fireEvent(order, arg, cl); } public void start(){ try{ Properties p =System.getProperties(); p.put("java.rmi.server.codebase","http://dimsrvli/appli/TomLib.jar"); System.setProperties(p); System.out.println("Start server"); Registry r = LocateRegistry.getRegistry(); System.out.println("Start server - get registry ok"); r.rebind("TomServer", this); System.out.println("Tom Server is ready 08"); } catch(Exception e){ e.printStackTrace(); } } public void connect(Client cl, String id_user) throws RemoteException { System.out.println("Connecting on serveur"); try{ synchronized(v_user){ v_user.put(cl, id_user); } System.out.println("connexion d'un nouveau client "+id_user); cl.getOrderFromServer("Bonjour à vous "+id_user+"!",null); } catch(Exception e){ e.printStackTrace(); } } public void refreshClient(){ try{ Iterator it; System.out.println("BroadCast Client : "+v_user.size()); synchronized(v_user){ System.out.println("MAJ Iterator"); it = v_user.keySet().iterator(); } while(it.hasNext()){ Client cl_courant = (Client)it.next(); try{ String id = (String) v_user.get(cl_courant); System.out.println("# "+id+" "+cl_courant.getClass()); cl_courant.getOrderFromServer("Connected?",null); System.out.println(id+" is connected !"); } catch(Exception e){ e.printStackTrace(); System.out.println("!!! Disconnect "+cl_courant); disconnect(cl_courant); } } } catch(Exception ee){ ee.printStackTrace(); } } public void addListener(MyRmiServListener mrl){ synchronized(listener){ //System.out.println("Add listener !! "+this); listener.add(mrl); //System.out.println("Add listener !! "+listener.size()); } } public void fireEvent(String order, String arg, Client cl) { synchronized(listener){ Iterator it = listener.iterator(); //System.out.println("while listener !! "+listener.size()+" "+this); while(it.hasNext()){ //System.out.println("boucle serveur listener"); MyRmiServListener mrl = (MyRmiServListener)it.next(); mrl.distantOrder(order, arg, cl); } } } public void disconnect(Client cl) throws RemoteException { try { String id = (String) v_user.get(cl); //String id = ""; System.out.println(id+" is disconnected !"); synchronized (v_user) { v_user.remove(cl); } } catch (Exception e) { e.printStackTrace(); } } }
La méthode du serveur refreshClient est lancée toutes les 5 sec via un cron et la librairie java quartz.
Le résultat de la console serveur :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
54
55
56
57
58
59
60 Cron event refreshclient Fri Nov 14 11:17:57 CET 2008 BroadCast Client : 0 MAJ Iterator Cron event refreshclient Fri Nov 14 11:18:02 CET 2008 BroadCast Client : 0 MAJ Iterator Cron event refreshclient Fri Nov 14 11:18:07 CET 2008 BroadCast Client : 0 MAJ Iterator Cron event refreshclient Fri Nov 14 11:18:12 CET 2008 BroadCast Client : 0 MAJ Iterator Connecting on serveur connexion d'un nouveau client dim8 Cron event refreshclient Fri Nov 14 11:18:17 CET 2008 BroadCast Client : 1 MAJ Iterator # dim8 class $Proxy1 dim8 is connected ! Cron event refreshclient Fri Nov 14 11:18:22 CET 2008 BroadCast Client : 1 MAJ Iterator # dim8 class $Proxy1 dim8 is connected ! Cron event refreshclient Fri Nov 14 11:18:27 CET 2008 BroadCast Client : 1 MAJ Iterator # dim8 class $Proxy1 dim8 is connected ! Cron event refreshclient Fri Nov 14 11:18:32 CET 2008 BroadCast Client : 1 MAJ Iterator # dim8 class $Proxy1 dim8 is connected ! --> Je tue le client dim8 Cron event refreshclient Fri Nov 14 11:18:37 CET 2008 BroadCast Client : 1 MAJ Iterator # dim8 class $Proxy1 Cron event refreshclient Fri Nov 14 11:18:42 CET 2008 BroadCast Client : 1 MAJ Iterator # dim8 class $Proxy1 Cron event refreshclient Fri Nov 14 11:18:47 CET 2008 BroadCast Client : 1 MAJ Iterator # dim8 class $Proxy1
Donc voila mon problème...l'instance de client n'existe a priori plus une fois le client terminé...pourtant dans la méthode refreshClient, je n'entre jamais dans le catch...
L'appel de la méthode cl_courant.getOrderFromServer("Connected?",null); sur une instance de client n'existant plus ne provoque pas de catch...et ne rend pas la main
A terme, lors de la fermeture de mon interface client, j'enverrai un ordre au serveur pour déconnecter proprement le client, mais j'aimerai trouver une solution plus propre permettant de ne pas planter le serveur suite a un crash de client...
Si quelqu'un a une idée, je suis bien entendu preneur...s'il faut des informations supplémentaires, je me tiens a votre disposition.
Je vous remercie d'avance...
Partager