| 1 package com.quikj.client.framework; 2 3 import java.net.*; 4 import java.util.*; 5 import java.io.*; 6 7 public class ServerCommunications 8 extends Thread  9 { 10 public static final String METHOD_PLUGIN = "SERVICE"; 11 public static final String METHOD_PING = "PING"; 12 public static final String PLUGIN_APP_ID = "Plugin-Id"; 13 public static final String CORRELATION_ID = "Correlation-Id"; 14 public static final String CONTENT_TYPE = "Content-Type"; 15 public static final String CONTENT_LENGTH = "Content-Length"; 16 public static final String CODE = "X-Encoding"; 17 18 public static final String PLAIN_TEXT = "text/plain"; 19 20 public static final int IOEXCEPTION = 1; 21 public static final int WRITE_ERROR = 2; 22 23 private Random random = new Random((new Date()).getTime()); 24 25 private boolean quit = false; 26 private HTTPConnectionClosedInterface closedListener = null; 27 private HTTPMessageListenerInterface requestListener = null; 28 private Socket socket; 29 private BufferedWriter ostream; 30 private int errorNumber = 0; 31 private InetAddress address; 32 private int port; 33 private int applicationId; 34 35 private Hashtable pendingRequests = new Hashtable(); 36 private Object pendingRequestsLock = new Object (); 37 private TimeoutHandler timeoutHandler; 38 private PingTimer pingTimerThread; 39 40 private static int correlationId = 1; 41 private static Object correlationLock = new Object (); 42 43 private HTTPParser parser = null; 44 45 public ServerCommunications(String host, int port, int app_id) 47 throws UnknownHostException 48 { 49 address = InetAddress.getByName(host); 50 this.port = port; 51 applicationId = app_id; 52 } 53 54 public String getHost() 55 { 56 return address.getHostName(); 57 } 58 59 public int getPort() 60 { 61 return port; 62 } 63 64 public int getApplicationId() 65 { 66 return applicationId; 67 } 68 69 public boolean connect() 70 { 71 try 73 { 74 socket = new Socket(address, port); 75 try 76 { 77 socket.setTcpNoDelay(true); 78 } 79 catch (SocketException ex) 80 { 81 ; } 83 84 ostream = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); 85 } 86 catch (IOException ex) 87 { 88 disconnect(); 89 errorNumber = IOEXCEPTION; 90 return false; 91 } 92 93 timeoutHandler = new TimeoutHandler(); 94 timeoutHandler.start(); 95 96 pingTimerThread = new ServerCommunications.PingTimer(); 97 pingTimerThread.start(); 98 99 return true; 100 } 101 102 public boolean isConnected() 103 { 104 if (socket != null) 105 { 106 return true; 107 } 108 else 109 { 110 return false; 111 } 112 } 113 114 public void disconnect() 115 { 116 quit = true; 117 118 if (timeoutHandler != null) 119 { 120 if (timeoutHandler.isAlive() == true) 121 { 122 timeoutHandler.interrupt(); 123 } 124 timeoutHandler = null; 125 } 126 127 if (pingTimerThread != null) 128 { 129 if (pingTimerThread.isAlive() == true) 130 { 131 pingTimerThread.interrupt(); 132 } 133 pingTimerThread = null; 134 } 135 136 if (isAlive() == true) 138 { 139 this.interrupt(); 140 } 141 142 if (parser != null) 144 { 145 parser.setInterrupted(true); 146 } 147 } 148 149 public void setRequestListener(HTTPMessageListenerInterface obj) 150 { 151 requestListener = obj; 152 } 153 154 public void setClosedListener(HTTPConnectionClosedInterface obj) 155 { 156 closedListener = obj; 157 } 158 159 private void restartPingTimer() 160 { 161 if (pingTimerThread != null) 163 { 164 if (pingTimerThread.isAlive() == true) 165 { 166 pingTimerThread.interrupt(); 167 pingTimerThread.dispose(); 168 } 169 } 170 171 pingTimerThread = new ServerCommunications.PingTimer(); 172 pingTimerThread.start(); 173 } 174 175 public synchronized int sendRequestMessage(String content_type, 176 String method, 177 String body, 178 HTTPMessageListenerInterface obj, 179 int timeout, 180 boolean multiple_responses) 181 { 182 HTTPReqMessage message = new HTTPReqMessage(); 183 184 if (method == null) 185 { 186 method = METHOD_PLUGIN; 187 } 188 189 message.setMethod(method); 190 message.setURL("/"); 191 message.setVersion("1.1"); 192 193 if (content_type.length() == 0) { 195 content_type = PLAIN_TEXT; 196 } 197 198 message.addHeader(CONTENT_TYPE, content_type); 199 message.addHeader(PLUGIN_APP_ID, (new Integer (applicationId)).toString()); 200 201 int crl_id = 0; 202 synchronized (correlationLock) 203 { 204 crl_id = correlationId++; 205 } 206 message.addHeader(CORRELATION_ID, (new Integer (crl_id)).toString()); 207 208 209 if (body != null) 210 { 211 if (body.length() > 0) 212 { 213 String code = generateRandomString(); 214 215 message.addHeader (CODE, 216 (new DESEncryption()).encrypt(code, 217 SysParam.getAuth2(getClass()))); 218 219 String encoded = (new DESEncryption()).encrypt(body, code); 221 222 message.setBody(encoded.toCharArray()); 223 } 224 } 225 226 if (obj != null) { 228 long timeout_date = 0L; 229 if (timeout > 0) { 231 timeout_date = (new Date()).getTime() + timeout; 232 } 233 234 synchronized (pendingRequestsLock) 236 { 237 pendingRequests.put(new Integer (crl_id), 238 new PendingResponseInfo(crl_id, obj, timeout_date, 239 multiple_responses)); 240 } 242 } 243 244 try 246 { 247 String formatted_message = message.format(); 248 249 ostream.write(formatted_message, 0, formatted_message.length()); 250 ostream.flush(); 251 } 252 catch (IOException ex) 253 { 254 errorNumber = WRITE_ERROR; 256 257 if (obj != null) { 259 synchronized (pendingRequestsLock) 261 { 262 pendingRequests.remove(new Integer (crl_id)); 263 } 264 } 265 266 return -1; 267 } 268 269 271 restartPingTimer(); 272 return crl_id; 273 } 274 275 public int sendRequestMessage(String content_type, 277 String body, 278 HTTPMessageListenerInterface obj, 279 int timeout, 280 boolean multiple_responses) 281 { 282 return sendRequestMessage(content_type, null, body, obj, timeout, 283 multiple_responses); 284 } 285 286 public int sendRequestMessage(String content_type, 288 String body, 289 HTTPMessageListenerInterface obj) 290 { 291 return sendRequestMessage(content_type, null, body, obj, 0, false); 292 } 293 294 public int sendRequestMessage(String content_type, 296 String body, 297 HTTPMessageListenerInterface obj, 298 boolean multiple_responses) 299 { 300 return sendRequestMessage(content_type, null, body, obj, 0, multiple_responses); 301 } 302 303 public int sendRequestMessage(String content_type, 305 String body, 306 HTTPMessageListenerInterface obj, 307 int timeout) 308 { 309 return sendRequestMessage(content_type, null, body, obj, timeout, false); 310 } 311 312 public int sendRequestMessage(String content_type, String body) 314 { 315 return sendRequestMessage(content_type, null, body, null, 0, false); 316 } 317 318 public int sendPing() 320 { 321 return sendRequestMessage("", METHOD_PING, null, null, 0, false); 323 } 324 325 public void cancelRequest(int id) 326 { 327 synchronized (pendingRequestsLock) 328 { 329 pendingRequests.remove(new Integer (id)); 331 } 332 } 333 334 335 public void cancelTimeout(int id) 336 { 337 changeTimeout(id, 0L); 338 } 339 340 public void changeTimeout(int id, long timeout) 341 { 342 PendingResponseInfo info = (PendingResponseInfo)pendingRequests.get(new Integer (id)); 343 if (info != null) 344 { 345 info.setTimeout(timeout); 346 } 347 } 348 349 public boolean sendResponse(int req_id, int status, String reason, 350 String content_type, String body) 351 { 352 HTTPRspMessage message = new HTTPRspMessage(); 353 354 message.setVersion("1.1"); 355 message.setStatus((new Integer (status)).toString()); 356 357 if (reason.length() > 0) 358 { 359 message.setReason(reason); 360 } 361 362 message.addHeader(PLUGIN_APP_ID, (new Integer (applicationId)).toString()); 363 message.addHeader(CORRELATION_ID, (new Integer (req_id)).toString()); 364 365 if (body != null) 366 { 367 if (body.length() > 0) 368 { 369 if (content_type.length() == 0) { 371 content_type = PLAIN_TEXT; 372 } 373 message.addHeader(CONTENT_TYPE, content_type); 374 375 String code = generateRandomString(); 376 377 message.addHeader (CODE, 378 (new DESEncryption()).encrypt(code, 379 SysParam.getAuth2(getClass()))); 380 381 String encoded = (new DESEncryption()).encrypt(body, code); 383 384 message.setBody(encoded.toCharArray()); 385 } 386 } 387 388 try 390 { 391 String rmessage = message.format(); 392 ostream.write(rmessage, 0, rmessage.length()); 393 ostream.flush(); 394 } 395 catch (IOException ex) 396 { 397 errorNumber = WRITE_ERROR; 399 return false; 400 } 401 402 return true; 403 } 404 405 private String generateRandomString() 406 { 407 char[] c = new char[10]; 408 409 for (int i = 0; i < 10; i++) 410 { 411 int x = random.nextInt() % 26; 412 c[i] = Integer.toString(Character.getNumericValue('a') + x, 10).charAt(0); 413 } 414 415 return new String (c); 416 } 417 418 public void run() 419 { 420 parser = null; 421 try 422 { 423 parser = new HTTPParser(socket); 424 } 425 catch (SocketException ex1) 426 { 427 return; 428 } 429 catch (IOException ex2) 430 { 431 return; 432 } 433 434 while (true) 435 { 436 HTTPMessage message = parser.read(); 437 438 if (message == null) 439 { 440 if ((parser.getErrorNumber() == HTTPParser.EOF) || 441 (parser.getErrorNumber() == HTTPParser.INTERRUPTED) || 442 (parser.getErrorNumber() == HTTPParser.IO_ERROR)) 443 { 444 if (quit == false) 445 { 446 disconnect(); 447 if (closedListener != null) 448 { 449 closedListener.connectionClosed(address.getHostName(), 451 port, 452 applicationId); 453 } 454 } 455 456 try 457 { 458 socket.close(); 460 } 461 catch (IOException ex1) 462 { 463 ; 464 } 465 return; 466 } 467 } 469 else { 471 restartPingTimer(); 472 473 if ((message instanceof HTTPReqMessage) == true) 474 { 475 HTTPReqMessage req_message = (HTTPReqMessage)message; 477 478 if (req_message.getMethod().equalsIgnoreCase(METHOD_PLUGIN) == false) 479 { 480 continue; 482 } 483 484 String appl_s = req_message.findHeader(PLUGIN_APP_ID); 485 if (appl_s == null) { 487 continue; } 489 490 try 491 { 492 int appl_id = Integer.parseInt(appl_s); 493 494 if (appl_id != applicationId) 495 { 496 continue; } 499 } 500 catch (NumberFormatException ex) 501 { 502 continue; } 505 506 String crl_id_s = req_message.findHeader(CORRELATION_ID); 507 if (crl_id_s == null) { 509 continue; } 511 512 int crl_id = 0; 513 try 514 { 515 crl_id = Integer.parseInt(crl_id_s); 516 } 517 catch (NumberFormatException ex) 518 { 519 continue; } 522 523 String content_type = req_message.findHeader(CONTENT_TYPE); 524 if (content_type == null) { 526 content_type = PLAIN_TEXT; 527 } 528 529 String body = null; 530 if (message.getBodyLength() > 0) 531 { 532 body = new String (message.getBody()); 533 } 534 535 if (body != null) 536 { 537 String code = req_message.findHeader(CODE); 539 if (code != null) 540 { 541 String dec = (new DESEncryption()).decrypt(code, 542 SysParam.getAuth2(getClass())); 543 544 if (dec != null) 545 { 546 String dec_body = (new DESEncryption()).decrypt(body, dec); 548 if (dec_body != null) 549 { 550 body = dec_body; 551 } 552 } 553 } 554 } 555 556 if (requestListener != null) 557 { 558 try 559 { 560 requestListener.messageReceived(crl_id, 561 HTTPMessageListenerInterface.RECEIVED, 562 content_type, 563 0, 564 null, 565 body); 566 } 567 catch (Exception ex) 568 { 569 ex.printStackTrace(); 572 } 573 } 574 } 575 else { 577 HTTPRspMessage rsp_message = (HTTPRspMessage)message; 579 580 String appl_s = rsp_message.findHeader(PLUGIN_APP_ID); 581 if (appl_s == null) { 583 continue; } 585 586 try 587 { 588 int appl_id = Integer.parseInt(appl_s); 589 590 if (appl_id != applicationId) 591 { 592 continue; } 595 } 596 catch (NumberFormatException ex) 597 { 598 continue; } 601 602 String crl_id_s = rsp_message.findHeader(CORRELATION_ID); 603 if (crl_id_s == null) { 605 continue; } 607 608 int crl_id = 0; 609 try 610 { 611 crl_id = Integer.parseInt(crl_id_s); 612 } 613 catch (NumberFormatException ex) 614 { 615 continue; } 618 619 String status_s = rsp_message.getStatus(); 620 int status = 0; 621 try 622 { 623 status = Integer.parseInt(status_s); 624 } 625 catch (NumberFormatException ex) 626 { 627 continue; } 630 631 String reason = rsp_message.getReason(); 632 633 String content_type = rsp_message.findHeader(CONTENT_TYPE); 634 if (content_type == null) { 636 content_type = PLAIN_TEXT; 637 } 638 639 String body = null; 640 if (message.getBodyLength() > 0) 641 { 642 body = new String (message.getBody()); 643 } 644 645 if (body != null) 646 { 647 String code = rsp_message.findHeader(CODE); 649 if (code != null) 650 { 651 String dec = (new DESEncryption()).decrypt(code, 652 SysParam.getAuth2(getClass())); 653 654 if (dec != null) 655 { 656 String dec_body = (new DESEncryption()).decrypt(body, dec); 658 if (dec_body != null) 659 { 660 body = dec_body; 661 } 662 } 663 } 664 } 665 666 667 PendingResponseInfo info = null; 668 synchronized (pendingRequestsLock) 670 { 671 info = (PendingResponseInfo)pendingRequests.get(new Integer (crl_id)); 672 if (info == null) { 674 continue; 676 } 677 678 if (info.multipleResponse() == false) 679 { 680 pendingRequests.remove(new Integer (crl_id)); 682 } 683 } 684 685 HTTPMessageListenerInterface listener = info.getListener(); 687 if (listener != null) 688 { 689 try 690 { 691 listener.messageReceived(crl_id, 692 HTTPMessageListenerInterface.RECEIVED, 693 content_type, 694 status, 695 reason, 696 body); 697 } 698 catch (Exception ex) 699 { 700 ex.printStackTrace(); 703 } 704 } 705 } 706 } 707 } 708 } 709 710 public int getErrorNumber() 711 { 712 return errorNumber; 713 } 714 715 class TimeoutHandler extends Thread  717 { 718 public TimeoutHandler() 719 { 720 } 721 722 public void run() 723 { 724 try 725 { 726 while (true) 727 { 728 Thread.sleep(100); 730 731 if (quit == true) 732 { 733 return; 734 } 735 736 Vector expired_timers = new Vector(); 737 738 long cur_time = (new Date()).getTime(); 739 740 synchronized (pendingRequestsLock) 741 { 742 Enumeration values = pendingRequests.elements(); 743 while (values.hasMoreElements() == true) 744 { 745 PendingResponseInfo info = (PendingResponseInfo)values.nextElement(); 746 int crl_id = info.getRequestId(); 747 748 long timeout = info.getTimeout(); 749 if (timeout > 0) 750 { 751 if (cur_time >= timeout) { 753 pendingRequests.remove(new Integer (crl_id)); 756 757 HTTPMessageListenerInterface listener = info.getListener(); 758 if (listener != null) 759 { 760 expired_timers.addElement(info); 761 } 762 } 763 } 764 } 765 } 766 767 768 int size = expired_timers.size(); 769 for (int i = 0; i < size; i++) 770 { 771 PendingResponseInfo element = (PendingResponseInfo)expired_timers.elementAt(i); 773 774 element.getListener().messageReceived(element.getRequestId(), 775 HTTPMessageListenerInterface.TIMEOUT, 776 "", 777 0, 778 null, 779 null); 780 } 781 782 if (quit == true) 783 { 784 break; 785 } 786 } 787 } 788 catch (InterruptedException ex) 789 { 790 if (quit == true) 791 { 792 return; 793 } 794 } 795 } 796 } 797 798 class PingTimer extends Thread  799 { 800 private boolean go = true; 801 802 public PingTimer() 803 { 804 } 805 806 private void dispose() 807 { 808 go = false; 809 } 810 811 public void run() 812 { 813 try 814 { 815 int count = 0; 816 while (true) 817 { 818 sleep(1000L); 819 820 if (quit == true) 821 { 822 return; 823 } 824 825 if (go == false) 826 { 827 return; 828 } 829 830 count++; 831 if (count >= PING_TIMER) 832 { 833 sendPing(); 835 count = 0; 836 } 837 } 838 } 839 catch (InterruptedException ex) 840 { 841 ; } 843 } 844 845 private long PING_TIMER = 15 * 60; 847 } 848 849 } 850 851 | Popular Tags |