diff --git a/framework/assets/js/websocket.js b/framework/assets/js/websocket.js index 3f097112..18921737 100755 --- a/framework/assets/js/websocket.js +++ b/framework/assets/js/websocket.js @@ -30,16 +30,14 @@ // WebSocket Object. All listener methods are cleaned up! var WebSocket = global.WebSocket = function(url) { - // must be overloaded - this.onopen = null; - this.onmessage = null; - this.onclose = null; - this.onerror = null; - // get a new websocket object from factory (check com.strumsoft.websocket.WebSocketFactory.java) this.socket = WebSocketFactory.getInstance(url); // store in registry - WebSocket.store[this.socket.getId()] = this; + if(this.socket) { + WebSocket.store[this.socket.getId()] = this; + } else { + throw new Error('websocket instantiation failed! Address could be wrong.'); + } }; // storage to hold websocket object for later invokation of event methods @@ -62,6 +60,7 @@ WebSocket.store[evt._target]['onerror'].call(global, evt._data); } + // instance event methods WebSocket.prototype.send = function(data) { this.socket.send(data); } @@ -73,5 +72,23 @@ WebSocket.prototype.getReadyState = function() { this.socket.getReadyState(); } - + ///////////// Must be overloaded + WebSocket.prototype.onopen = function(){ + throw new Error('onopen not implemented.'); + }; + + // alerts message pushed from server + WebSocket.prototype.onmessage = function(msg){ + throw new Error('onmessage not implemented.'); + }; + + // alerts message pushed from server + WebSocket.prototype.onerror = function(msg){ + throw new Error('onerror not implemented.'); + }; + + // alert close event + WebSocket.prototype.onclose = function(){ + throw new Error('onclose not implemented.'); + }; })(); diff --git a/framework/src/com/phonegap/websocket/WebSocket.java b/framework/src/com/phonegap/websocket/WebSocket.java index 2e03d110..c0340806 100755 --- a/framework/src/com/phonegap/websocket/WebSocket.java +++ b/framework/src/com/phonegap/websocket/WebSocket.java @@ -43,6 +43,7 @@ import java.util.Set; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; +import android.util.Log; import android.webkit.WebView; /** @@ -246,17 +247,42 @@ public class WebSocket implements Runnable { // ////////////////////////////////////////////////////////////////////////////////////// /** * Starts a new Thread and connects to server + * + * @throws IOException */ - public void connect() { + public Thread connect() throws IOException { this.running = true; - (new Thread(this)).start(); + this.readyState = WEBSOCKET_STATE_CONNECTING; + // open socket + socketChannel = SocketChannel.open(); + socketChannel.configureBlocking(false); + // set address + socketChannel.connect(new InetSocketAddress(uri.getHost(), port)); + // start a thread to make connection + + // More info: + // http://groups.google.com/group/android-developers/browse_thread/thread/45a8b53e9bf60d82 + // http://stackoverflow.com/questions/2879455/android-2-2-and-bad-address-family-on-socket-connect + System.setProperty("java.net.preferIPv4Stack", "true"); + System.setProperty("java.net.preferIPv6Addresses", "false"); + + selector = Selector.open(); + socketChannel.register(selector, SelectionKey.OP_CONNECT); + Log.v("websocket", "Starting a new thread to manage data reading/writing"); + + Thread th = new Thread(this); + th.start(); + // return thread object for explicit closing, if needed + return th; } public void run() { - try { - _connect(); - } catch (IOException e) { - this.onError(e); + while (this.running) { + try { + _connect(); + } catch (IOException e) { + this.onError(e); + } } } @@ -265,7 +291,7 @@ public class WebSocket implements Runnable { */ public void close() { this.readyState = WebSocket.WEBSOCKET_STATE_CLOSING; - + // close socket channel try { this.socketChannel.close(); @@ -274,10 +300,10 @@ public class WebSocket implements Runnable { } this.running = false; selector.wakeup(); - + // fire onClose method this.onClose(); - + this.readyState = WebSocket.WEBSOCKET_STATE_CLOSED; } @@ -289,7 +315,7 @@ public class WebSocket implements Runnable { */ public void send(String text) { try { - if(this.readyState == WEBSOCKET_STATE_OPEN){ + if (this.readyState == WEBSOCKET_STATE_OPEN) { _send(text); } else { this.onError(new NotYetConnectedException()); @@ -389,45 +415,31 @@ public class WebSocket implements Runnable { // actual connection logic private void _connect() throws IOException { - this.readyState = WEBSOCKET_STATE_CONNECTING; - socketChannel = SocketChannel.open(); - socketChannel.configureBlocking(false); - socketChannel.connect(new InetSocketAddress(uri.getHost(), port)); - - // More info: - // http://groups.google.com/group/android-developers/browse_thread/thread/45a8b53e9bf60d82 - // http://stackoverflow.com/questions/2879455/android-2-2-and-bad-address-family-on-socket-connect - System.setProperty("java.net.preferIPv4Stack", "true"); - System.setProperty("java.net.preferIPv6Addresses", "false"); - - selector = Selector.open(); - socketChannel.register(selector, SelectionKey.OP_CONNECT); - // Continuous loop that is only supposed to end when "close" is called. - while (this.running) { - selector.select(); - Set keys = selector.selectedKeys(); - Iterator i = keys.iterator(); - while (i.hasNext()) { - SelectionKey key = i.next(); - i.remove(); - if (key.isConnectable()) { - if (socketChannel.isConnectionPending()) { - socketChannel.finishConnect(); - } - socketChannel.register(selector, SelectionKey.OP_READ); - _writeHandshake(); + selector.select(); + Set keys = selector.selectedKeys(); + Iterator i = keys.iterator(); + + while (i.hasNext()) { + SelectionKey key = i.next(); + i.remove(); + if (key.isConnectable()) { + if (socketChannel.isConnectionPending()) { + socketChannel.finishConnect(); } - if (key.isReadable()) { - try { - _read(); - } catch (NoSuchAlgorithmException nsa) { - this.onError(nsa); - } + socketChannel.register(selector, SelectionKey.OP_READ); + _writeHandshake(); + } + if (key.isReadable()) { + try { + _read(); + } catch (NoSuchAlgorithmException nsa) { + this.onError(nsa); } } } + } private void _writeHandshake() throws IOException { diff --git a/framework/src/com/phonegap/websocket/WebSocketFactory.java b/framework/src/com/phonegap/websocket/WebSocketFactory.java index 292241f8..9369454f 100755 --- a/framework/src/com/phonegap/websocket/WebSocketFactory.java +++ b/framework/src/com/phonegap/websocket/WebSocketFactory.java @@ -26,7 +26,6 @@ package com.phonegap.websocket; import java.net.URI; -import java.net.URISyntaxException; import java.util.Random; import android.webkit.WebView; @@ -53,14 +52,25 @@ public class WebSocketFactory { this.appView = appView; } - public WebSocket getInstance(String url) throws URISyntaxException { + public WebSocket getInstance(String url) { + // use Draft75 by default return getInstance(url, WebSocket.Draft.DRAFT75); } - public WebSocket getInstance(String url, WebSocket.Draft draft) throws URISyntaxException { - WebSocket socket = new WebSocket(appView, new URI(url), draft, getRandonUniqueId()); - socket.connect(); - return socket; + public WebSocket getInstance(String url, WebSocket.Draft draft) { + WebSocket socket = null; + Thread th = null; + try { + socket = new WebSocket(appView, new URI(url), draft, getRandonUniqueId()); + th = socket.connect(); + return socket; + } catch (Exception e) { + //Log.v("websocket", e.toString()); + if(th != null) { + th.interrupt(); + } + } + return null; } /**