WebSocket support in Android’s Phonegap apps
We are developing a small game which can be played from multiple users using variety of clients, web-browser, Android, iPhone, iPad etc. It’s like, there is a server and all clients connect to this server, and send and receive messages. We decided to use WebSocket for underlying connection between clients and server, and Phonegap to build clients. Our idea is to write the client once and then run it on variety of platforms. Since, Phonegap enables app development using HTML, CSS and JavaScripts, it generously fits into our requirement.
But Phonegap doesn’t support WebSocket yet, it’s in their Plan-of-Action for 1.x release though. So, it was needed to be addressed. I found Mathias Desloge’s PhoneGap-Android-HTML5-WebSocket project. It was good but it used old java.io.* packages. I would have preferred to use java.nio.* for better and efficient non-blocking behavior. So, I decided to write my own small library.
Library can be found here: websocket-android-phonegap.
How to use?
- Copy Java source into your source folder.
- Copy websocket.js in your assets/www/js folder
- Attach com.strumsoft.websocket.phonegap.WebSocketFactory to WebView, like
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); super.loadUrl("file:///android_asset/www/index.html"); // attach websocket factory appView.addJavascriptInterface(new WebSocketFactory(appView), "WebSocketFactory"); } - In your page, create a new WebSocket, and overload its method ‘onmessage’, ‘onopen’, ‘onclose’, like
// new socket var socket = new WebSocket('ws://192.168.1.153:8081'); // push a message after the connection is established. socket.onopen = function() { alert('connected'); }; // alerts message pushed from server socket.onmessage = function(msg) { alert(JSON.stringify(msg)); }; // alert close event socket.onclose = function() { alert('closed'); };
How it works?
When you create a new WebSocket object in your page, behind the scene, websocket.js delegates the responsibility to com.strumsoft.websocket.phonegap.WebSocketFactory to instantiate new com.strumsoft.websocket.phonegap.WebSocket object.
// websocket.js // get a new websocket object from factory (check com.strumsoft.websocket.WebSocketFactory.java) this.socket = WebSocketFactory.getWebSocket(url);
WebSocketFactory simply instantiates a new WebSocket object, connects it to the designated server and returns the instance.
// com.strumsoft.websocket.phonegap.WebSocketFactory
public WebSocket getWebSocket(String url) throws URISyntaxException {
WebSocket socket = new WebSocket(appView, new URI(url));
socket.connect(); // connects to server
return socket;
}
Now, whenever an event occurs, say, ‘onmessage’, WebSocket class delegates that event to Javascript.
// com.strumsoft.websocket.phonegap.WebSocket
public void onMessage(String message) {
appView.loadUrl(buildLoadData("message", message));
}
private String buildLoadData(String _event, String _data) {
String _d = "javascript:WebSocket.on" + _event + "(" +
"{"
+ "\"_target\":\"" + webSocketId + "\"," +
"\"_data\":'" + data + "'" +
"}" +
")";
Logger.log(_d);
return _d;
}
Finally, ‘WebSocket.onmessage’ from websocket.js is called. It parses the payload, finds out the target WebSocket object, and calls the corresponding event on the target object with event data.
// websocket.js
// static event methods to call event methods on target websocket objects
WebSocket.onmessage = function (evt) {
WebSocket.registry[evt._target]['onmessage'].call(global, evt._data);
}
That’s it!
Amendment
(Date: Thu Aug 25 12:40:52 IST 2011)
There was a serious bug! The Websocket connection runs in a separate thread to manage persistent state with the server. And the front end Javascript (websocket.js) stays within UI/Main thread. And Android doesn’t want other threads to communicate with UI thread directly. These threads must employ an additional thread to bridge the communication. So, here is the fix!
// a message is sent to server!
public void send(final String text) {
// new thread
new Thread(new Runnable() {
@Override
public void run() {
if (instance.readyState == WEBSOCKET_STATE_OPEN) {
try {
instance._send(text);
} catch (IOException e) {
instance.onError(e);
}
} else {
instance.onError(new NotYetConnectedException());
}
}
}).start();
}
// when a message is received
public void onMessage(final String msg) {
// post a new thread to View
appView.post(new Runnable() {
@Override
public void run() {
appView.loadUrl(buildJavaScriptData(EVENT_ON_MESSAGE, msg));
}
});
}
Commit link:
https://github.com/anismiles/websocket-android-phonegap/commit/a7ccb815cce3a446c3ec92058187cdb20e5a41e8
https://github.com/anismiles/websocket-android-phonegap/commit/087f7a93d46f92cb037d2b451a4d253a65f5f015





Really Nice and helpful….
Rajesh M
February 4, 2011 at 4:13 pm
OMG! Thank you so match!
mike
February 10, 2011 at 9:32 am
Hi, Thank you! I have one problem though
wghen using it in PhomeGap Android app all I can see “on the wire” when socket is create is:
####
T 192.168.1.65:50765 -> 192.168.1.51:8080 [AP]
GET / HTTP/1.1.
Upgrade: WebSocket.
Connection: Upgrade.
Host: 192.168.1.51:8080.
Origin: *.
.
#####
Headers:
Sec-WebSocket-Key1: ….
Sec-WebSocket-Key2: ….
are missing, therefore my sever is rejecting connection.
Any suggestions very much appreciated.
Regards,
Chris
Chris
February 12, 2011 at 9:54 pm
Chris, what’s your server? may be, your server needs Draft76 impl. Check that. You can change the Draft impl in WebSocketFactory which defaults to Draft75 for now.
-Animesh
Animesh
February 12, 2011 at 10:30 pm
Animesh, Thanks for prompt reply. I am using node.js (http://nodejs.org/) + Socket.IO Server (https://github.com/LearnBoost/Socket.IO-node).
I had a quick look into Draft76 and it seems to me Sec-WebSocket-Key1/2 headers are required in initial handshake from the client. See: http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-76#page-7
Any idea when they are not being sent?
Regards,
Chris
Chris
February 12, 2011 at 11:25 pm
Socket.IO implements Draft-76 of websocket api. You can go to WebSocketFactory class and change WebSocket.Draft.DRAFT75 to WebSocket.Draft.DRAFT76. Everything will automatically take care of itself after that.
-Animesh
Animesh
February 13, 2011 at 12:12 am
Thanks, once changed to WebSocket.Draft.DRAFT76 it works… however every now and than my App crashes with the following output in the console:
E/AndroidRuntime( 393): FATAL EXCEPTION: Thread-21
E/AndroidRuntime( 393): android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
E/AndroidRuntime( 393): at android.view.ViewRoot.checkThread(ViewRoot.java:2802)
E/AndroidRuntime( 393): at android.view.ViewRoot.invalidateChild(ViewRoot.java:607)
E/AndroidRuntime( 393): at android.view.ViewRoot.invalidateChildInParent(ViewRoot.java:633)
E/AndroidRuntime( 393): at android.view.ViewGroup.invalidateChild(ViewGroup.java:2505)
E/AndroidRuntime( 393): at android.view.View.invalidate(View.java:5139)
E/AndroidRuntime( 393): at android.view.View.onFocusChanged(View.java:2664)
E/AndroidRuntime( 393): at android.widget.TextView.onFocusChanged(TextView.java:6469)
E/AndroidRuntime( 393): at android.widget.AutoCompleteTextView.onFocusChanged(AutoCompleteTextView.java:1048)
E/AndroidRuntime( 393): at android.webkit.WebTextView.onFocusChanged(WebTextView.java:357)
E/AndroidRuntime( 393): at android.view.View.clearFocusForRemoval(View.java:2577)
E/AndroidRuntime( 393): at android.view.ViewGroup.removeViewInternal(ViewGroup.java:2188)
E/AndroidRuntime( 393): at android.view.ViewGroup.removeViewInternal(ViewGroup.java:2181)
E/AndroidRuntime( 393): at android.view.ViewGroup.removeView(ViewGroup.java:2129)
E/AndroidRuntime( 393): at android.webkit.WebTextView.remove(WebTextView.java:583)
E/AndroidRuntime( 393): at android.webkit.WebView.clearTextEntry(WebView.java:1830)
E/AndroidRuntime( 393): at android.webkit.WebView.loadUrl(WebView.java:1542)
E/AndroidRuntime( 393): at android.webkit.WebView.loadUrl(WebView.java:1553)
E/AndroidRuntime( 393): at com.myapp.Test.WebSocket.onClose(WebSocket.java:318)
E/AndroidRuntime( 393): at com.myapp.Test.WebSocket.close(WebSocket.java:280)
E/AndroidRuntime( 393): at com.myapp.Test.WebSocket._read(WebSocket.java:493)
E/AndroidRuntime( 393): at com.myapp.Test.WebSocket._connect(WebSocket.java:425)
E/AndroidRuntime( 393): at com.myapp.Test.WebSocket.run(WebSocket.java:258)
E/AndroidRuntime( 393): at java.lang.Thread.run(Thread.java:1096)
W/ActivityManager( 59): Force finishing activity com.myapp.Test/.Test
Any idea how to fix that?
Chris
February 15, 2011 at 10:04 pm
Chris,
I am a bit skeptical about Socket.IO. I ran some tests, here is how:
1. Cloned https://github.com/LearnBoost/Socket.IO-node
2. Ran example chat server: sudo node server.js
3. Went to browser and opened: http://localhost:8080/ which took me to chat.html and that worked perfectly fine. However, I am not sure if it used WebSocket or Log-Poll or what? So, I wrote a simple script to connect to the chat server using Browser’s websocket object!
// new socket try { var socket = new WebSocket('ws://localhost:8080/'); // push a message after the connection is established. socket.onopen = function(){ alert('connected'); }; // alerts message pushed from server socket.onmessage = function(msg){ alert(JSON.stringify(msg)); }; // alerts message pushed from server socket.onerror = function(msg){ alert(JSON.stringify(msg)); }; // alert close event socket.onclose = function(){ alert('closed'); }; // now, post a message the connection after 10 secons. setInterval(function(){ socket.send({ message: ['you', 'animesh'] }); }, 10000); } catch (e) { alert(e); }Well, as I guessed, it didn’t work. It couldn’t open the connection. That means, Socket.IO examples must be using long-polling or flash socket sorts fall back mechanism.
Hey, why don’t you try implementing websocket server using https://github.com/miksago/node-websocket-server This seemed to work fine with browser and the phonegap plugin i wrote. Here is an example: http://anismiles.wordpress.com/2011/01/25/websocket-and-node-js-why-shud%E2%80%99ya-care/
Animesh
February 16, 2011 at 5:12 pm
I’m getting the exact same error as Chris: an CalledFromWrongThreadException – I’m getting on when onmessage fires.
Any updates on this issue?
Full trace:
03-02 13:53:04.788: ERROR/AndroidRuntime(6585): FATAL EXCEPTION: Thread-14
03-02 13:53:04.788: ERROR/AndroidRuntime(6585): android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
03-02 13:53:04.788: ERROR/AndroidRuntime(6585): at android.view.ViewRoot.checkThread(ViewRoot.java:2824)
03-02 13:53:04.788: ERROR/AndroidRuntime(6585): at android.view.ViewRoot.invalidateChild(ViewRoot.java:611)
03-02 13:53:04.788: ERROR/AndroidRuntime(6585): at android.view.ViewRoot.invalidateChildInParent(ViewRoot.java:637)
03-02 13:53:04.788: ERROR/AndroidRuntime(6585): at android.view.ViewGroup.invalidateChild(ViewGroup.java:2513)
03-02 13:53:04.788: ERROR/AndroidRuntime(6585): at android.view.View.invalidate(View.java:5138)
03-02 13:53:04.788: ERROR/AndroidRuntime(6585): at android.view.View.onFocusChanged(View.java:2663)
03-02 13:53:04.788: ERROR/AndroidRuntime(6585): at android.widget.TextView.onFocusChanged(TextView.java:6595)
03-02 13:53:04.788: ERROR/AndroidRuntime(6585): at android.widget.AutoCompleteTextView.onFocusChanged(AutoCompleteTextView.java:1097)
03-02 13:53:04.788: ERROR/AndroidRuntime(6585): at android.webkit.WebTextView.onFocusChanged(WebTextView.java:360)
03-02 13:53:04.788: ERROR/AndroidRuntime(6585): at android.view.View.clearFocusForRemoval(View.java:2576)
03-02 13:53:04.788: ERROR/AndroidRuntime(6585): at android.view.ViewGroup.removeViewInternal(ViewGroup.java:2196)
03-02 13:53:04.788: ERROR/AndroidRuntime(6585): at android.view.ViewGroup.removeViewInternal(ViewGroup.java:2189)
03-02 13:53:04.788: ERROR/AndroidRuntime(6585): at android.view.ViewGroup.removeView(ViewGroup.java:2137)
03-02 13:53:04.788: ERROR/AndroidRuntime(6585): at android.webkit.WebTextView.remove(WebTextView.java:589)
03-02 13:53:04.788: ERROR/AndroidRuntime(6585): at android.webkit.WebView.clearTextEntry(WebView.java:2027)
03-02 13:53:04.788: ERROR/AndroidRuntime(6585): at android.webkit.WebView.loadUrl(WebView.java:1691)
03-02 13:53:04.788: ERROR/AndroidRuntime(6585): at android.webkit.WebView.loadUrl(WebView.java:1702)
03-02 13:53:04.788: ERROR/AndroidRuntime(6585): at com.strumsoft.websocket.phonegap.WebSocket.onMessage(WebSocket.java:336)
03-02 13:53:04.788: ERROR/AndroidRuntime(6585): at com.strumsoft.websocket.phonegap.WebSocket._readFrame(WebSocket.java:531)
03-02 13:53:04.788: ERROR/AndroidRuntime(6585): at com.strumsoft.websocket.phonegap.WebSocket._read(WebSocket.java:512)
03-02 13:53:04.788: ERROR/AndroidRuntime(6585): at com.strumsoft.websocket.phonegap.WebSocket._connect(WebSocket.java:437)
03-02 13:53:04.788: ERROR/AndroidRuntime(6585): at com.strumsoft.websocket.phonegap.WebSocket.run(WebSocket.java:283)
03-02 13:53:04.788: ERROR/AndroidRuntime(6585): at java.lang.Thread.run(Thread.java:1102)
Per Erik Gransøe
March 2, 2011 at 6:29 pm
Chris was able to remove this error. However, he started having another stupid issue, that is, his app keeps getting crash after some time of usage. We both are looking into this. let’s see if we would be able to do something about it here.
Animesh
March 2, 2011 at 6:42 pm
Ok. Could you post a thing about Chris’ short term solution?
I’m looking forward to hear about your final solution to the problem.
Per Erik Gransøe
March 2, 2011 at 6:55 pm
Hi,
I need some help regarding iPhone app. Do you have any idea how to add another splash image while loading app as my app is quite heavy. I know your post is regarding android app. But I am asking if you an help me in anyway as I am using Phonegap to convert my app..
Thanks
Preet
May 16, 2011 at 5:24 am
Per Erik Gransøe, Chris
This problem is resolved now. https://github.com/anismiles/websocket-android-phonegap/commit/a7ccb815cce3a446c3ec92058187cdb20e5a41e8
Animesh
August 25, 2011 at 12:13 pm
This WebSocket-Solution is really good, but a little bit slow, if you want receive “big data”-Token (e.g. a 200kb)
I have rewritten the read-Method for Tokens, the code for the handshake is still the same. Here are my changes:
New Variables:
/** Big buffer for tokens. Default 500kb */
private ByteBuffer bigBuffer = ByteBuffer.allocate(1024 * 500);
private byte[] tokenByteBuffer = new byte[1024 * 500];
private int tokenByteBufferCounter = 0;
Changed “_read”-Method:
private void _read() throws IOException, NoSuchAlgorithmException {
int bytesRead = -1;
try {
if (!handshakeComplete) {
buffer.rewind();
bytesRead = socketChannel.read(this.buffer);
buffer.rewind();
} else {
bigBuffer.rewind();
bytesRead = socketChannel.read(this.bigBuffer);
bigBuffer.rewind();
}
} catch (Exception ex) {
Log.v(LOG_TAG, “Could not read data from socket channel, ex=” + ex.toString());
}
if (bytesRead == -1) {
Log.v(LOG_TAG, “All Bytes readed”);
close();
} else if (bytesRead > 0) {
if (!this.handshakeComplete) {
_readHandshake();
} else {
_readFrame(bytesRead);
}
}
}
Changed “_readFrame”-Method:
private void _readFrame(int bytesReaded) throws UnsupportedEncodingException {
byte[] data = bigBuffer.array();
int length = bytesReaded;
if (length > 2000) length = 2000;
Log.v(LOG_TAG, “_readFrame – bytesReaded: ” + bytesReaded + “, data: ” + new String(data, 0, length));
// Get tokens
for (int i=0; i < bytesReaded; i++) {
byte readedByte = data[i];
// Token message is finished
if (readedByte == DATA_END_OF_FRAME) {
// Make token public
this.onMessage(new String(tokenByteBuffer, 0, tokenByteBufferCounter));
// Reset counter for byte buffer
tokenByteBufferCounter = 0;
// Bytes to read as token message, skip start frame byte
} else if (readedByte != DATA_START_OF_FRAME) {
tokenByteBufferCounter++;
// Array is out of bounds, make it greater
if (tokenByteBufferCounter == tokenByteBuffer.length) {
byte[] newTokenByteBuffer = new byte[tokenByteBuffer.length*2];
Log.v(LOG_TAG, "expand token byte buffer, new size=" + newTokenByteBuffer.length);
// Copy old data
for (int i2=0; i2<tokenByteBuffer.length; i2++) {
newTokenByteBuffer[i2] = tokenByteBuffer[i2];
}
tokenByteBuffer = newTokenByteBuffer;
}
tokenByteBuffer[tokenByteBufferCounter-1] = readedByte;
}
}
}
Changed "buildJavaScriptData"-Method:
I must changed the method, because the message was quoted and the data-value was added, when no message was available, this produced errors:
private String buildJavaScriptData(String event, String token) {
String javaScript = "javascript:WebSocket." + event + "(";
// Beginn JSON part, wrap token with a target-id
String jSON = "{" + "_target:\"" + id + "\"";
// Token received, add it
if (token != null && token.trim().length() != 0) {
jSON = jSON + "," + "data:";
// Contains no multiple data, quot the it
if (!token.startsWith("{")) {
jSON+="\"" + token + "\"";
// Don't quote the token
} else {
jSON += token;
}
}
// Close JSON part
jSON = jSON + "}";
javaScript = javaScript + jSON + ")";
Log.i(LOG_TAG, "buildJavaScriptData: javaScript=" + javaScript);
return javaScript;
}
Manuel Beck
October 13, 2011 at 1:24 pm
Here’s a formatted version of my comment:
This WebSocket-Solution is really good, but a little bit slow, if you want receive “big data”-Token (e.g. a 200kb)
I have rewritten the read-Method for Tokens, the code for the handshake is still the same. Here are my changes:
New Variables:
Changed “_read”-Method:
private void _read() throws IOException, NoSuchAlgorithmException { int bytesRead = -1; try { if (!handshakeComplete) { buffer.rewind(); bytesRead = socketChannel.read(this.buffer); buffer.rewind(); } else { bigBuffer.rewind(); bytesRead = socketChannel.read(this.bigBuffer); bigBuffer.rewind(); } } catch (Exception ex) { Log.v(LOG_TAG, “Could not read data from socket channel, ex=” + ex.toString()); } if (bytesRead == -1) { Log.v(LOG_TAG, “All Bytes readed”); close(); } else if (bytesRead > 0) { if (!this.handshakeComplete) { _readHandshake(); } else { _readFrame(bytesRead); } } }Changed “_readFrame”-Method:
private void _readFrame(int bytesReaded) throws UnsupportedEncodingException { byte[] data = bigBuffer.array(); int length = bytesReaded; if (length > 2000) length = 2000; Log.v(LOG_TAG, “_readFrame – bytesReaded: ” + bytesReaded + “, data: ” + new String(data, 0, length)); // Get tokens for (int i=0; i < bytesReaded; i++) { byte readedByte = data[i]; // Token message is finished if (readedByte == DATA_END_OF_FRAME) { // Make token public this.onMessage(new String(tokenByteBuffer, 0, tokenByteBufferCounter)); // Reset counter for byte buffer tokenByteBufferCounter = 0; // Bytes to read as token message, skip start frame byte } else if (readedByte != DATA_START_OF_FRAME) { tokenByteBufferCounter++; // Array is out of bounds, make it greater if (tokenByteBufferCounter == tokenByteBuffer.length) { byte[] newTokenByteBuffer = new byte[tokenByteBuffer.length*2]; Log.v(LOG_TAG, "expand token byte buffer, new size=" + newTokenByteBuffer.length); // Copy old data for (int i2=0; i2<tokenByteBuffer.length; i2++) { newTokenByteBuffer[i2] = tokenByteBuffer[i2]; } tokenByteBuffer = newTokenByteBuffer; } tokenByteBuffer[tokenByteBufferCounter-1] = readedByte; } } }Changed “buildJavaScriptData”-Method:
I must changed the method, because the message was quoted and the data-value was added, when no message was available, this produced errors:
private String buildJavaScriptData(String event, String token) { String javaScript = "javascript:WebSocket." + event + "("; // Begin JSON part, wrap token with a target-id String jSON = "{" + "_target:\"" + id + "\""; // Token received, add it if (token != null && token.trim().length() != 0) { jSON = jSON + "," + "data:"; // Contains no multiple data, quot the it if (!token.startsWith("{")) { jSON+="\"" + token + "\""; // Don't quote the token } else { jSON += token; } } // Close JSON part jSON = jSON + "}"; javaScript = javaScript + jSON + ")"; Log.i(LOG_TAG, "buildJavaScriptData: javaScript=" + javaScript); return javaScript; }Manuel Beck
October 13, 2011 at 1:41 pm
Thanks Manuel! This is wonderful. I will add these changes to my code base on Github. Or, may be, if you have a forked project, you can send a PULL request?
-Animesh
Animesh
October 13, 2011 at 9:21 pm
Hi Animesh,
sadly i haven’t a forked project. I just copied your source from GitHub. Im glad, that my code is useful for you:)
Greetings, Manuel B.
Manuel Beck
October 14, 2011 at 1:49 pm
During the development with WebSocket and PhoneGap, i got the problem, that the Android keyboard was dismissed, if the JavaScript-environment got a new token from server. This problem occured, if the native Android-WebSocket solutions sends tokens to the javascript environment, for e.g.:
A solution, i give the WebSocket class my DroidGap instance, and call the javascript functions directly via:
This will let the keyboard from android always be visible.
Manuel B.
December 20, 2011 at 8:26 pm
Thanks a lot this really helped me a lot.
Hiren
February 7, 2012 at 10:57 pm
Glad to know that, Hiren.
Animesh
February 9, 2012 at 9:41 am
Hi. I have some issue with this library.
I get some validation errors: “The method run() of type new Runnable(){} must override a superclass method WebSocket.java” (five times).
I use eclipse with JDK compiler compliance level 1.7. (I think it is up to date).
How could I solve this problem?
Thanks.
Jorge
February 29, 2012 at 1:28 pm
Hi again, I have solved the problem. I have config my project to use SDK 1.6 and it works good now. Using 1.7 gets this error.
Now I can compile and run it on android emulator but the socket open and close inmediately.
I have a tested websocket server running and listening, but It doesn’t connect to it.
Jorge
February 29, 2012 at 6:22 pm
Hi again. After a lot of test I think the problem is with my server, but I don’t know why.
I use the project from: http://code.google.com/p/bauglir-websocket/
to make a websocket server with Embarcadero Delphi 2010. This server works good. I have tested it with a websocket client using chrome and with the page: http://websocket.org/echo.html , putting location to my ip.
All test work good with my server.
But I can’t connect with the android app using your websocket+phonegap. If I change the ws address to “ws://echo.websocket.org”, works good, but if I set it to “ws://localhost:8081″ It doesn’t work. I have change the port, and test with local IP, with another computer over the lan, and other test without success.
What could be the problem? Protocol? Draft?
Thanks.
Jorge
February 29, 2012 at 11:38 pm
I believe your websocket server is not bound to localhost. Check that.
Animesh
March 1, 2012 at 11:44 am
Hi. Thanks, but I don’t think so.
I have tested it with local ip “ws://192.168.0.10:8080″, with differents ports (80, 81, 8787, 8081, etc).
And I’ve tested it with another computer on my LAN “ws://192.168.0.9:81″, and with differents ports again.
It always works good with this simple websocket cliente using google chrome:
<!DOCTYPE HTML> <html lang='es'> <head> <meta charset="utf-8" /> <script> var socket = null; function doLoad() { socket = new WebSocket("ws//192.168.0.10:8081", ['proto1', 'proto2']); socket.binaryType = 'arraybuffer'; socket.onopen = function (event) { console.log(event); }; socket.onmessage = function (event) { console.log(event.data); }; socket.onerror = function (event) { console.log(event); }; socket.onclose = function (event) { console.log(event); socket = null; }; setInterval(function() { if (socket && socket.readyState == socket.OPEN) { socket.send('hello'); } }, 3000); } </script> <title>WS1</title> </head> <body onload="doLoad();"> <p>Very simple websocket client</p> </body> </html>But with your app with android+phonegap it doesn’t. I’ve test it using android emulator and with a android tablet (2.3).
Jorge
March 1, 2012 at 12:57 pm
Can you share your Android JS code?
Animesh
March 1, 2012 at 6:26 pm
Hi. I’m using your js example code.
But I have found the problem. It’s relative to the initial handshake.
My server was expecting: “Sec-WebSocket-Key” but you send Sec-WebSocket-Key1 and Sec-WebSocket-Key2. And other stuff relative to this. I switch to DRAF76 but I doesn’t work. Reading your java code I see that.
I have change my server a now it works good.
This is the information that came at the end of the pascal unit:
{ GET / HTTP/1.1 Upgrade: websocket Connection: Upgrade Host: 81.0.231.149:81 Sec-WebSocket-Origin: http://html5.bauglir.dev Sec-WebSocket-Key: Q9ceXTuzjdF2o23CRYvnuA== Sec-WebSocket-Version: 8 GET / HTTP/1.1 Host: 81.0.231.149:81 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:6.0) Gecko/20100101 Firefox/6.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: sk,cs;q=0.8,en-us;q=0.5,en;q=0.3 Accept-Encoding: gzip, deflate Accept-Charset: ISO-8859-2,utf-8;q=0.7,*;q=0.7 Connection: keep-alive, Upgrade Sec-WebSocket-Version: 7 Sec-WebSocket-Origin: http://html5.bauglir.dev Sec-WebSocket-Key: HgBKcPfdBSzjCYxGnWCO3g== Pragma: no-cache Cache-Control: no-cache Upgrade: websocket Cookie: __utma=72544661.1949147240.1313811966.1313811966.1313811966.1; __utmb=72544661.3.10.1313811966; __utmc=72544661; __utmz=72544661.1313811966.1.1.utmcsr=localhost|utmccn=(referral)|utmcmd=referral|utmcct=/websocket/index.php 1300}As you can see, the messages are lightly different. I have fix it and now it works good.
thanks for your library.
Jorge
March 1, 2012 at 10:19 pm
Ah! Wonderful. I am glad I could help.
Animesh
March 1, 2012 at 10:58 pm
Hello, i am trying to use this plugin with activemq server, but no connection is opened in the server side. When i test in chrome (with the lib https://github.com/jmesnil/stomp-websocket) my server (activemq 5.6-SNAPSHOT) works great. But with phonegap and this plugin not.
There is a way to make this plugin works with activemq server?
Thanks in advance,
Arthur
arthurgod
March 16, 2012 at 7:28 am
Even I am stuck in same situation.Is there any way to implement activemq ,stomp protocol with Phonegap?
Pallavi
April 3, 2012 at 11:39 am