1 20 21 package org.jdesktop.jdic.browser; 22 23 import java.io.*; 24 import java.nio.*; 25 import java.nio.channels.*; 26 import java.nio.charset.*; 27 import java.net.*; 28 import java.util.*; 29 30 import org.jdesktop.jdic.browser.internal.WebBrowserUtil; 31 32 38 class MsgClient { 39 private static final int MAX_RETRY = 30; 40 private static final int BUFFERSIZE = 2048; 41 42 private static final String MSG_DELIMITER = "</html><body></html>"; 45 private static final String MSG_DELIMITER_ = MSG_DELIMITER + "_"; 48 private static final String MSG_DELIMITER_HEAD = MSG_DELIMITER + "_head"; 49 private static final String MSG_DELIMITER_MIDDLE = MSG_DELIMITER + "_middle"; 50 private static final String MSG_DELIMITER_END = MSG_DELIMITER + "_end"; 51 52 private Selector selector = null; 53 private SocketChannel channel = null; 54 private int port; 55 private InetSocketAddress serverAddr; 56 57 private String charsetName = null; 58 private CharsetDecoder decoder; 59 private CharsetEncoder encoder; 60 private ByteBuffer buffer; 61 private CharBuffer charBuffer; 62 63 private String sendBuffer = new String (); 64 private String recvBuffer = new String (); 65 66 private static Set msgPieces = new HashSet(); 69 70 MsgClient() { 71 charsetName = WebBrowserUtil.isDefaultBrowserMozilla() ? 77 "UTF-8" : System.getProperty("file.encoding"); 78 79 Charset charset = Charset.forName(charsetName); 80 decoder = charset.newDecoder(); 81 encoder = charset.newEncoder(); 82 83 buffer = ByteBuffer.allocateDirect(BUFFERSIZE); 84 charBuffer = CharBuffer.allocate(BUFFERSIZE); 85 86 try { 87 selector = Selector.open(); 89 90 ServerSocketChannel sc = ServerSocketChannel.open(); 91 sc.socket().bind(new InetSocketAddress("localhost", 0)); 93 port = sc.socket().getLocalPort(); 94 sc.close(); 95 sc = null; 96 serverAddr = new InetSocketAddress("localhost", port); 97 WebBrowserUtil.trace("found a free port: " + port); 98 } catch (Exception e) { 99 } 100 } 101 102 int getPort() { 103 return port; 104 } 105 106 void connect() throws IOException, InterruptedException { 107 int retry; 108 for (retry = 0; retry < MAX_RETRY; retry++) { 109 WebBrowserUtil.trace("connecting ... " + retry); 110 111 try { 112 channel = SocketChannel.open(); 113 channel.configureBlocking(false); 114 channel.connect(serverAddr); 116 channel.register(selector, SelectionKey.OP_CONNECT); 118 119 while (! channel.isConnected()) { 120 if (selector.select(1) > 0) { 121 Set readyKeys = selector.selectedKeys(); 122 Iterator i = readyKeys.iterator(); 123 while (i.hasNext()) { 124 SelectionKey key = (SelectionKey)i.next(); 125 i.remove(); 126 SocketChannel keyChannel = (SocketChannel) key.channel(); 127 if (key.isConnectable()) { 128 if (keyChannel.isConnectionPending()) { 129 keyChannel.finishConnect(); 130 } 131 break; 132 } 133 } 134 } 135 } 136 break; 137 } catch (Exception e) { 138 WebBrowserUtil.trace(e.toString()); 139 channel.close(); 140 channel = null; 141 try { 142 Thread.sleep(150); 143 } catch (Exception ex) { 144 } 145 } 146 147 } 148 149 if (retry == MAX_RETRY) { 150 throw new InterruptedException ("Maximum retry number reached!"); 151 } 152 153 WebBrowserUtil.trace("connected"); 154 channel.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE); 155 } 156 157 void sendMessage(String msg) { 162 sendBuffer += msg + MSG_DELIMITER; 163 } 164 165 String getMessage() { 166 int pos = recvBuffer.indexOf(MSG_DELIMITER); 167 if (pos < 0) 168 return null; 169 170 String msg = recvBuffer.substring(0, pos); 171 if (pos != recvBuffer.indexOf(MSG_DELIMITER_)) { 172 recvBuffer = recvBuffer.substring(pos + 174 (new String (MSG_DELIMITER).length())); 175 WebBrowserUtil.trace("get a complete short message: " + msg); 176 return msg; 177 } 178 179 NativeEventData eventData = NativeEventThread.parseIncomingMessage(msg); 180 181 if (pos == recvBuffer.indexOf(MSG_DELIMITER_HEAD)) { 184 msgPieces.add(new NativeEventData(eventData.instance, 188 eventData.type, eventData.stringValue)); 189 recvBuffer = recvBuffer.substring(pos + 190 (new String (MSG_DELIMITER_HEAD).length())); 191 WebBrowserUtil.trace("get a head message piece: " 192 + eventData.stringValue); 193 return null; 194 } else { 195 Iterator it = msgPieces.iterator(); 196 while (it.hasNext()) { 197 NativeEventData element = (NativeEventData)it.next(); 198 if ((element.instance == eventData.instance) && 199 (element.type == eventData.type)) { 200 if (pos == recvBuffer.indexOf(MSG_DELIMITER_MIDDLE)) { 201 NativeEventData newElement = new NativeEventData( 202 eventData.instance, eventData.type, 203 element.stringValue + eventData.stringValue); 204 msgPieces.remove(element); 205 msgPieces.add(newElement); 206 recvBuffer = recvBuffer.substring(pos + 207 (new String (MSG_DELIMITER_MIDDLE).length())); 208 WebBrowserUtil.trace("got a middle message piece: " + 209 eventData.stringValue); 210 return null; 211 } else if (pos == recvBuffer.indexOf(MSG_DELIMITER_END)) { 212 msg = eventData.instance + "," + eventData.type + "," 215 + element.stringValue + eventData.stringValue; 216 msgPieces.remove(element); 217 recvBuffer = recvBuffer.substring(pos + 218 (new String (MSG_DELIMITER_END).length())); 219 WebBrowserUtil.trace("got an end message piece: " + 220 eventData.stringValue); 221 WebBrowserUtil.trace("got a complete long message: " + 222 element.stringValue + eventData.stringValue); 223 224 return (msg); 225 } 226 } 227 } 228 229 return null; 230 } 231 } 232 233 void portListening() throws IOException, InterruptedException { 234 if (selector != null && selector.select(1) > 0) { 235 Set readyKeys = selector.selectedKeys(); 236 Iterator i = readyKeys.iterator(); 237 while (i.hasNext()) { 238 SelectionKey key = (SelectionKey)i.next(); 239 i.remove(); 240 SocketChannel keyChannel = (SocketChannel) key.channel(); 241 if (key.isReadable()) { 242 buffer.clear(); 243 charBuffer.clear(); 244 keyChannel.read(buffer); 245 buffer.flip(); 246 decoder.decode(buffer, charBuffer, false); 247 charBuffer.flip(); 248 recvBuffer += charBuffer; 249 WebBrowserUtil.trace("read data from socket: " 250 + recvBuffer); 251 } 252 else if (key.isWritable()) { 253 if (sendBuffer.length() > 0) { 254 WebBrowserUtil.trace("send data to socket: " 255 + sendBuffer); 256 ByteBuffer buf 257 = ByteBuffer.wrap(sendBuffer.getBytes(charsetName)); 258 keyChannel.write(buf); 259 sendBuffer = ""; 260 } 261 } 262 } 263 } 264 } 265 } 266 | Popular Tags |