Salut à tous,
j'essaie d'optimiser un programme assez conséquent qui a quelques problèmes de lag sur une fois sur internet. avant, a chaque envoi de message on créait une nouvelle socket, on envoyait un message et on attendait de recevoir l'acquittement... j'essaie de simplifier tout ça en séparant les méthodes d'envoi réception à l'aide d'une classe SocketHelper

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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
public class SocketHelper {
 
	private SSLSocket 	socket;
	private String		hostname;
	private int			port;
	private	int			timeOut;
 
	/**
         * SocketHelper constructor for clients
         * @param hostname
         * @param port
         * @param timeOut
         */
	public SocketHelper(String hostname, int port, int timeOut){
		try {			
			this.hostname 	= hostname;
			this.port 		= port;
			this.timeOut 	= timeOut;
			// SSL Socket
			SSLSocketFactory sslFact = (SSLSocketFactory) SSLSocketFactory.getDefault();
			socket = (SSLSocket) sslFact.createSocket(hostname, port);
			String set[] = new String[] { "SSL_RSA_WITH_NULL_MD5" };
			socket.setEnabledCipherSuites(set);
			socket.setReceiveBufferSize(48000);
			socket.setSendBufferSize(48000);
			socket.setTcpNoDelay(true);
			if (timeOut != 0)
				socket.setSoTimeout(timeOut);
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
 
	/**
         * SocketHelper constructor for server (with accept)
         * @param sslSocket
         */
	public SocketHelper(SSLSocket sslSocket){			
		try {
			this.socket 	= sslSocket;
			this.hostname 	= socket.getInetAddress().getHostName();
			this.port 		= socket.getPort();
			this.timeOut 	= socket.getSoTimeout();
 
			String set[] = new String[] { "SSL_RSA_WITH_NULL_MD5" };
			socket.setEnabledCipherSuites(set);
			socket.setReceiveBufferSize(48000);
			socket.setSendBufferSize(48000);
			socket.setTcpNoDelay(true);
		} catch (SocketException e) {
			e.printStackTrace();
		}
	}
 
	/**
         * Send compressed data
         * @param object
         * @return true if sent, else false
         */
	public boolean write(Object o){		
		if(socket != null && socket.isConnected() && !socket.isClosed()){
			try {
				OutputStream os = socket.getOutputStream();
				GZIPOutputStream gos = new GZIPOutputStream(os);
				BufferedOutputStream bos = new BufferedOutputStream(gos);
				ObjectOutputStream out = new ObjectOutputStream(bos);
 
				out.writeObject(o);
				out.flush();
				bos.flush();
				gos.finish();
 
				return true;
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return false;
	}
 
	/**
         * Read compressed data
         * @return object
         */
	public Object read(){
		if(socket != null && socket.isConnected() && !socket.isClosed()){
			try {
				InputStream is = socket.getInputStream();
				GZIPInputStream gis = new GZIPInputStream(is);
				BufferedInputStream bis = new BufferedInputStream(gis);
				ObjectInputStream in 	= new ObjectInputStream(bis);
				return in.readObject();
			} catch (EOFException e){
				System.out.println("debug : EOF on socket : "+hostname+":"+port);
				close();
			} catch (IOException e) {
				e.printStackTrace();
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
			}
		}
		return null;
	}
 
	/**
         * Close the socket
         * @return true if closed, else false
         */
	public boolean close(){
		if(socket != null){
			try {
				socket.close();
				return true;
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return false;
	}
 
	/**
         * Get the socket
         * @return socket
         */
	public Socket getSocket(){
		return socket;
	}
 
	/**
         * Get Remote Host Name attached to the socket
         * @return hostname
         */
	public String getHostname() {
		return hostname;
	}
 
	/**
         * Get Remote Port attached to the socket
         * @return
         */
	public int getPort() {
		return port;
	}
 
	/**
         * Get read time out (ms)
         * @return timeOut
         */
	public int getTimeOut() {
		return timeOut;
	}
 
	/**
         * Set the read time out (ms)
         * @param timeOut
         * @return
         */
	public boolean setTimeOut(int timeOut) {
		if(socket != null){
			try {
				socket.setSoTimeout(timeOut);
				this.timeOut = timeOut;
				return true;
			} catch (SocketException e) {
				e.printStackTrace();
			}
		}
		return false;
	}
}
J'essaie ensuite d'utiliser la même socket pour tous les échanges, avec un gestionnaire de requêtes traitant les messages reçus. (ClientThread).
Les classes qui ont besoin d'envoyer un message le font par appel a CMCThread.getInstance.write(...) et c'est le CMCThread qui leur renvoie la réponse éventuelle.

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
 
public class CMCThread extends Thread {
 
	private static CMCThread	_instance;
	private SocketHelper 		socketHelper;
	private LoginThread 		loginThread;
	private RealTimeThread		realTimeThread;
 
	private CMCThread(){
		socketHelper = new SocketHelper(Activator.getStringVal(CMCConfigKey.Server_IP),
				Integer.valueOf(Activator.getStringVal(CMCConfigKey.Server_Port)),
				3000);
		socketHelper.setForcedOnline(true);
	}
 
	public static CMCThread getInstance(){
		if(_instance == null)
			_instance = new CMCThread();
		return _instance;
	}
 
	public boolean write(Object o){
		return socketHelper.write(o);
	}
 
	public void setLoginThread(LoginThread lt){
		this.loginThread = lt;
	}
 
	public void setRealTimeThread(RealTimeThread rt){
		this.realTimeThread = rt;
	}
 
	public void run(){
 
		while(socketHelper.getSocket() != null){
			Object obj = socketHelper.read();
 
			if(obj instanceof LoginRequest){
				try {
					loginThread.receiveAnswer((LoginRequest) obj);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
 
			if(obj instanceof CRequest){
				switch(((CRequest) obj).getType()){
					case RequestConstants.AGENT_SEND_REALTIME_DATA :
						try {
							realTimeThread.passRequest((CRequest) obj);
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
						break;
					default :
						System.out.println("debug : received "+((CRequest) obj).getType());
						break;
				}
 
			}
		}
	}
}
Je voudrais votre avis sur tout ça, car bien que ça aie l'air de marcher, j'ai un problème qui revient assez souvent (un message sur 15/20) :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
java.io.IOException: Not in GZIP format
remonté par par le socketHelper.read de mon thread et plus précisément par cette ligne dans SocketHelper : GZIPInputStream gis = new GZIPInputStream(is);
J'ai vu quelques cas similaires sur internet mais je n'ai pas réussi à enlever ce problème ( qui n'éxistait pas en créant une socket à chaque envoi de message ) . J'ai réalisé la même chose dans les autres programmes (le serveur et un autre client) qui rencontrent le même problème alors que les messages n'ont pas changé !

Merci de votre aide !