ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/cms/source/conient/uk/org/iscream/cms/conient/ConnectionHandler.java
(Generate patch)

Comparing projects/cms/source/conient/uk/org/iscream/cms/conient/ConnectionHandler.java (file contents):
Revision 1.11 by ajm, Wed Jan 24 03:21:26 2001 UTC vs.
Revision 1.12 by ajm, Sun Jan 28 23:48:16 2001 UTC

# Line 82 | Line 82 | public class ConnectionHandler extends Thread {
82       */
83      public static final int QUIT = 5;
84  
85 +    /**
86 +     * This is the time in seconds that this class
87 +     * should wait on the DataReader class to fully
88 +     * shutdown after calling shutdown() before
89 +     * forcing a shutdown
90 +     */
91 +    public static final int DATAREADER_SHUTDOWN_TIMEOUT = 5;
92 +
93   //---STATIC METHODS---
94  
95   //---CONSTRUCTORS---
# Line 121 | Line 129 | public class ConnectionHandler extends Thread {
129              try {
130                  action = ((Integer) _actionQueue.get(_myQueue)).intValue();
131              } catch (InvalidQueueException e) {
132 <                // we 're never going to get this...
132 >                // we 're never going to get this
133 >                // but if we do we should do something nasty
134 >                throw new RuntimeException("unable to retrieve events from actionQueue!");
135              }
136              
137              // examine our action...
138              // if it was to connect...then we connect...
139              switch(action) {
140                  case CONNECT:
141 <                
142 <                    Object serverQuestion = null;
143 <                    serverQuestion = JOptionPane.showInputDialog(null, "Please enter the name of a server running the I-Scream client interface:", "I-Scream Server", JOptionPane.INFORMATION_MESSAGE);
144 <                    if (serverQuestion instanceof String) {
145 <                        _server = (String) serverQuestion;
146 <                        Conient.setControlStatus("Connecting to - " + _server);
147 <                        try {
148 <                            _controlLink = new Socket(_server, _port);
149 <                            _inBound = new BufferedReader(new InputStreamReader(_controlLink.getInputStream()));
150 <                            _outBound = new PrintWriter(_controlLink.getOutputStream());
151 <                            Conient.setControlStatus("Connection Established - " + _server);
152 <                            String response;
153 <                            response = _inBound.readLine();
154 <                            if (!(Double.parseDouble(response.substring(10, response.length())) > PROTOCOL_VERSION)) {
155 <                                Conient.addMessage("WARNING: server is using a newer protocol (" + response + "), please update your client, continuing with old protocol (PROTOCOL " + PROTOCOL_VERSION + ")" );
156 <                            } else if (!(Double.parseDouble(response.substring(10, response.length())) < PROTOCOL_VERSION)) {
157 <                                throw new IOException("invalid protocol version");
141 >                    if (_controlLink == null) {
142 >                        // get the server name  
143 >                        Object serverQuestion = null;
144 >                        serverQuestion = JOptionPane.showInputDialog(null, "Please enter the name of a server running the I-Scream client interface:", "I-Scream Server", JOptionPane.INFORMATION_MESSAGE);
145 >                        if (serverQuestion instanceof String) {
146 >                            _server = (String) serverQuestion;
147 >                            Conient.setControlStatus("Connecting to - " + _server);
148 >                            try {
149 >                                // open the socket to the server and bind the IO
150 >                                _controlLink = new Socket(_server, _port);
151 >                                _inBound = new BufferedReader(new InputStreamReader(_controlLink.getInputStream()));
152 >                                _outBound = new PrintWriter(_controlLink.getOutputStream());
153 >                                Conient.setControlStatus("Connection Established - " + _server);
154 >    
155 >                                String response;
156 >                                response = _inBound.readLine();
157 >    
158 >                                // check the servers Protocol Identity against our own
159 >                                // we SHOULD be backwards compatible, so we can continue if
160 >                                // they are using a newer protocol, anything else then we die
161 >                                if (!(Double.parseDouble(response.substring(10, response.length())) > PROTOCOL_VERSION)) {
162 >                                    Conient.addMessage("WARNING{control link}: server is using a newer protocol (" + response + "), please update your client, continuing with old protocol (PROTOCOL " + PROTOCOL_VERSION + ")" );
163 >                                } else if (!(Double.parseDouble(response.substring(10, response.length())) < PROTOCOL_VERSION)) {
164 >                                    // tidy up
165 >                                    throw new IOException("incompatible protocol version");
166 >                                }
167 >                                
168 >                                // send the name of the client
169 >                                _outBound.println(_clientName);
170 >                                _outBound.flush();
171 >                                response = _inBound.readLine();
172 >                                if (!response.equals("OK")) {
173 >                                    // tidy up
174 >                                    
175 >                                    throw new IOException("client name rejected - " + _clientName);
176 >                                }
177 >                            } catch (IOException e) {
178 >                                // print the error and tidy up what's left
179 >                                Conient.addMessage("ERROR{control link}: " + e);
180 >                                _controlLink = null;
181 >                                Conient.setControlStatus("Disconnected");
182                              }
149                            Conient.addMessage("Handshake Success");
150                            
151                            // send the name - get from somewhere eventually
152                            _outBound.println(_clientName);
153                            _outBound.flush();
154                            response = _inBound.readLine();
155                            if (!response.equals("OK")) {
156                                throw new IOException("client name rejected - " + response);
157                            }
158                            Conient.addMessage("Control Link Established");
159
160                        } catch (IOException e) {
161                            Conient.addMessage("Control Link Error: " + e);
162                            Conient.setControlStatus("Disconnected");
183                          }
184 +                    } else {
185 +                        Conient.addMessage("WARNING{control link}: already established");
186                      }
187                      break;
188                  case STARTDATA:
189 <                    Conient.addMessage("Attempting to open Data Channel");
190 <                    try {
189 >                    // as long as the data link hasn't been established
190 >                    // we want to establish it
191 >                    if (_dataLink == null) {
192 >                        // check that the control link is open, if it isn't we
193 >                        // might want to sort that problemo out
194 >                        // we do this by simply queueing the event to occour, then
195 >                        // this event to run again ;-)
196                          if(_controlLink == null) {
197 +                            Conient.addMessage("WARNING{data link}: control link not established - queueing start events");
198                              _actionQueue.add(new Integer(CONNECT));
199                              _actionQueue.add(new Integer(STARTDATA));
200 <                            throw new IOException("Control Link not establised - queueing start events");
200 >                        } else {
201 >                            try {
202 >                                                          
203 >                                // ask the server to start the data link
204 >                                String response;
205 >                                _outBound.println("STARTDATA");
206 >                                _outBound.flush();
207 >                                response = _inBound.readLine();
208 >                                // TEMPORARY FIREWALL FIX
209 >                                // allows user to map an ssh pipe...
210 >                                JOptionPane.showMessageDialog(null, "WARNING: about to connect to a port you may not have available!\nPlease ensure you have port \"" + response + "\" of your I-Scream server mapped to " + _server, "FIREWALL WARNING!", JOptionPane.INFORMATION_MESSAGE);
211 >                                Conient.setDataStatus("Connecting to - " + _server + ":" + response);
212 >                                
213 >                                // see if the server suggested a good port
214 >                                if (response.equals("ERROR")) {
215 >                                    throw new IOException("server unable to start data link at this time");
216 >                                }
217 >                                try {
218 >                                    _dataLink = new Socket(_server, Integer.parseInt(response));
219 >                                } catch (NumberFormatException e) {
220 >                                    throw new IOException("invalid data port suggested by server - " + response);
221 >                                }
222 >                                
223 >                                response = _inBound.readLine();
224 >                                if (!response.equals("OK")) {
225 >                                    throw new IOException("server reported error establishing data channel");
226 >                                }
227 >                                
228 >                                // if the socket was ok, then we attack our IO hooks
229 >                                _dataInBound = new BufferedReader(new InputStreamReader(_dataLink.getInputStream()));
230 >                                _dataOutBound = new PrintWriter(_dataLink.getOutputStream());
231 >                                Conient.setDataStatus("Connection Established - " + _server);
232 >                            } catch (IOException e) {
233 >                                // print the error and tidy up what's left
234 >                                Conient.addMessage("ERROR{data link}: " + e);
235 >                                _dataLink = null;
236 >                                Conient.setDataStatus("Disconnected");
237 >                            }
238 >                            // now we want to start reading the data in
239 >                            // so we start the appropriate components on their way
240 >                            // we create a queue to give to both the reader and the
241 >                            // displayer
242 >                            Queue theQueue = new Queue();
243 >                            _dataReader = new DataReader(_dataInBound, theQueue);
244 >                            _data.setQueue(theQueue);
245 >                            _data.cleanUpTabs();
246 >                            
247 >                            // start the data rocking
248 >                            new Thread(_data).start();
249 >                            _dataReader.start();
250 >                            // finished for us....
251                          }
252 <                        String response;
253 <                        _outBound.println("STARTDATA");
176 <                        _outBound.flush();
177 <                        response = _inBound.readLine();
178 <                        
179 <                        // TEMPORARY FIREWALL FIX
180 <                        // allows user to map an ssh pipe...
181 <                        JOptionPane.showMessageDialog(null, "WARNING: about to connect to a port you may not have available!\nPlease ensure you have port \"" + response + "\" of your I-Scream server mapped to " + _server, "FIREWALL WARNING!", JOptionPane.INFORMATION_MESSAGE);
182 <                        Conient.setDataStatus("Connecting to - " + _server + ":" + response);
183 <                        try {
184 <                            _dataLink = new Socket(_server, Integer.parseInt(response));
185 <                        } catch (NumberFormatException e) {
186 <                            throw new IOException("error, invalid data port suggested by server - " + response);
187 <                        }
188 <                        
189 <                        response = _inBound.readLine();
190 <                        if (!response.equals("OK")) {
191 <                            throw new IOException("server reported error establishing data channel - " + response);
192 <                        }
193 <                        _dataInBound = new BufferedReader(new InputStreamReader(_dataLink.getInputStream()));
194 <                        _dataOutBound = new PrintWriter(_dataLink.getOutputStream());
195 <                        Conient.setDataStatus("Connection Established - " + _server);
196 <                        Conient.addMessage("Data Link connection established");
197 <                        Conient.addMessage("Starting data reader");
198 <
199 <                        // here we will do some connect stuff.
200 <                        Queue theQueue = new Queue();
201 <                        _dataReader = new DataReader(_dataInBound, theQueue);
202 <                        _data.setQueue(theQueue);
203 <                        _data.cleanUpTabs();
204 <                        new Thread(_data).start();
205 <                        _dataReader.start();
206 <                        // finished for us....
207 <                    } catch (IOException e) {
208 <                        Conient.addMessage("Data Link Error: " + e);
209 <                        Conient.setDataStatus("Disconnected");
252 >                    } else {
253 >                        Conient.addMessage("WARNING{data link}: already established");
254                      }
255                      break;
256                  case STOPDATA:
257 <                    Conient.addMessage("Attempting to close Data Channel");
258 <                    try {
259 <                        String response;
260 <                        _outBound.println("STOPDATA");
261 <                        _outBound.flush();
262 <                        response = _inBound.readLine();
263 <                        if (!response.equals("OK")) {
264 <                            throw new IOException("server didn't OK request to stop data channel");
257 >                    if(_dataLink != null) {
258 >                        try {
259 >                            String response;
260 >                            // shut down the data link
261 >                            Conient.setDataStatus("Disconnecting - " + _server);
262 >                            
263 >                            // close the reader
264 >                            _dataReader.shutdown();
265 >                            // wait for it to close
266 >                            boolean dirtyShutdown = true;
267 >                            long startTime = System.currentTimeMillis();
268 >                            while((System.currentTimeMillis() - startTime) < (DATAREADER_SHUTDOWN_TIMEOUT * 1000)) {
269 >                                if (!_dataReader.isAlive()) {
270 >                                    dirtyShutdown = false;
271 >                                    break;
272 >                                }
273 >                            }
274 >                            // warn if it didn't shutdown in time
275 >                            if (dirtyShutdown) {
276 >                                Conient.addMessage("WARNING{data link}: data reader thread did not close within timeout, killing its IO anyway!");
277 >                            }
278 >                            
279 >                            // tell the server
280 >                            _outBound.println("STOPDATA");
281 >                            _outBound.flush();
282 >                            response = _inBound.readLine();
283 >                            
284 >                            // check the server was ok with our request...
285 >                            // even if it wasn't we will go anyway!
286 >                            if (!response.equals("OK")) {
287 >                                throw new IOException("server didn't OK request to stop data channel - stopping anyway");
288 >                            }
289 >                            
290 >                            
291 >                            // close the lot down
292 >                            _dataInBound.close();
293 >                            _dataOutBound.close();
294 >                            _dataLink.close();
295 >                            // get rid of the socket
296 >                            _dataLink = null;
297 >                            Conient.setDataStatus("Disconnected");
298 >                        } catch (IOException e) {
299 >                            // print the error and tidy up what's left
300 >                            Conient.addMessage("ERROR{data link}: " + e);
301 >                            try {
302 >                                _dataOutBound.close();
303 >                                _dataInBound.close();
304 >                                _dataLink.close();
305 >                            } catch (IOException e2) {
306 >                                    Conient.addMessage("CRITICAL{control link}: unable to close socket - " + e2);
307 >                            }
308 >                            _dataLink = null;
309 >                            Conient.setDataStatus("Disconnected");
310                          }
311 <                        // kill the data reader - we should wait
312 <                        // for it to die nicely...but we won't yet...we'll kill the socket! ;-p
224 <                        Conient.setDataStatus("Disconnecting - " + _server);
225 <                        _dataReader.shutdown();
226 <                        _dataInBound.close();
227 <                        _dataOutBound.close();
228 <                        _dataLink.close();
229 <                        // get rid of the socket
230 <                        _dataLink = null;
231 <                        Conient.setDataStatus("Disconnected");
232 <                        Conient.addMessage("Data Channel closed");
233 <                    } catch (IOException e) {
234 <                        Conient.addMessage("Data Link Error: " + e);
235 <                        Conient.setDataStatus("Unknown");
311 >                    } else {
312 >                        Conient.addMessage("WARNING{data link}: already disconnected");
313                      }
314                      break;
315                  case DISCONNECT:
316 <                    Conient.addMessage("Attempting to close Control Channel");
240 <                    try {
316 >                    if (_controlLink != null) {
317                          if (_dataLink != null) {
318 <                            // we want to tell ourselves to stop it
319 <                            _actionQueue.add(new Integer(STOPDATA));
320 <                            _actionQueue.add(new Integer(DISCONNECT));
321 <                            throw new IOException("Warning - Data Channel not closed - attempting to close it!");
318 >                                // we want to tell ourselves to stop it
319 >                                Conient.addMessage("WARNING{control link}: data link not disconnected - queueing stop events");
320 >                                _actionQueue.add(new Integer(STOPDATA));
321 >                                _actionQueue.add(new Integer(DISCONNECT));
322 >                        } else {
323 >                            try {
324 >                                // request the server to disconnect
325 >                                String response;
326 >                                _outBound.println("DISCONNECT");
327 >                                _outBound.flush();
328 >                                response = _inBound.readLine();
329 >                                
330 >                                // check the server was ok with our request...
331 >                                // even if it wasn't we will go anyway!
332 >                                if (!response.equals("OK")) {
333 >                                    throw new IOException("server didn't OK request to stop control channel - stopping anyway");
334 >                                }
335 >                                
336 >                                // then lets shutdown the link
337 >                                Conient.setControlStatus("Disconnecting - " + _server);
338 >                                _inBound.close();
339 >                                _outBound.close();
340 >                                _controlLink.close();
341 >                                // for good measure
342 >                                _controlLink = null;
343 >                                Conient.setControlStatus("Disconnected");
344 >                            } catch (IOException e) {
345 >                                Conient.addMessage("Control Link Error: " + e);
346 >                                try {
347 >                                    _inBound.close();
348 >                                    _outBound.close();
349 >                                    _controlLink.close();
350 >                                } catch (IOException e2) {
351 >                                    Conient.addMessage("CRITICAL{control link}: unable to close socket - " + e2);
352 >                                }
353 >                                _controlLink = null;
354 >                                Conient.setControlStatus("Disconnected");
355 >                            }
356                          }
357 <                        String response;
358 <                        _outBound.println("DISCONNECT");
249 <                        _outBound.flush();
250 <                        response = _inBound.readLine();
251 <                        if (!response.equals("OK")) {
252 <                            throw new IOException("server didn't OK request to stop control channel");
253 <                        }
254 <                        // then lets go!
255 <                        Conient.setControlStatus("Disconnecting - " + _server);
256 <                        _inBound.close();
257 <                        _outBound.close();
258 <                        _controlLink.close();
259 <                        // for good measure
260 <                        _controlLink = null;
261 <                        Conient.setControlStatus("Disconnected");
262 <                    } catch (IOException e) {
263 <                        Conient.addMessage("Control Link Error: " + e);
264 <                        Conient.setControlStatus("Unknown");
357 >                    } else {
358 >                        Conient.addMessage("WARNING{control link}: already disconnected");
359                      }
360                      break;
361                  case QUIT:
362 <                    Conient.addMessage("Exiting...");
362 >                    Conient.addMessage("Exiting.");
363                      try {
364                          // stop data and control if data up
365                          if (_dataLink != null) {
# Line 284 | Line 378 | public class ConnectionHandler extends Thread {
378                          // go!
379                          System.exit(0);
380                      } catch (IOException e) {
381 <                        Conient.addMessage("Closing connections...");
381 >                        Conient.addMessage("WARNING: open connections detected - queueing stop events");
382                      }
383                      break;
384 +                
385              }
386          }
387      }
388      
389 +    /**
390 +     * This method allows other classes
391 +     * to shutdown this connection handler.
392 +     */
393 +    public void shutdown() {
394 +        _running = false;
395 +    }
396 +    
397   //---PRIVATE METHODS---
398  
399   //---ACCESSOR/MUTATOR METHODS---
400  
401   //---ATTRIBUTES---      
402  
403 +    /**
404 +     * The state if this thread
405 +     */
406      boolean _running = true;
407 <    Conient Conient;
407 >    
408 >    /**
409 >     * A reference to the displaying class DataPanel
410 >     */
411      DataPanel _data;
412 +    
413 +    /**
414 +     * The queue that actions are added to by other parts of the system
415 +     */
416      Queue _actionQueue;
417 +    
418 +    /**
419 +     * The queue number that we are reading from on the action queue
420 +     */
421      int _myQueue;
422 +    
423 +    /**
424 +     * The FQDN of the i-scream server we are connecting to
425 +     */
426      String _server;
427 +    
428 +    /**
429 +     * The port that is running the client interface on the i-scream server
430 +     */  
431      int _port = Conient.PORT;
432 +    
433 +    /**
434 +     * The control link socket
435 +     */
436      Socket _controlLink;
437 +    
438 +    /**
439 +     * The data link socket
440 +     */
441      Socket _dataLink;
442 +    
443 +    /**
444 +     * The input for the control link
445 +     */
446      BufferedReader _inBound;
447 +    
448 +    /**
449 +     * The output for the control link
450 +     */
451      PrintWriter _outBound;
452 +    
453 +    /**
454 +     * The input for the data link
455 +     */
456      BufferedReader _dataInBound;
457 +    
458 +    /**
459 +     * The output for the data link
460 +     */
461      PrintWriter _dataOutBound;
462 +    
463 +    /**
464 +     * A reference to the DataReader in use
465 +     */
466      DataReader _dataReader;
467 +    
468 +    /**
469 +     * The friendly identifier of this client
470 +     * that is sent to the server
471 +     */
472      String _clientName = "Conient";
473  
474   //---STATIC ATTRIBUTES---

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines