Open RedHotScalability opened 12 years ago
Hi @RedHotScalability!
Thanks for using socket.io-java-client. :D
The reason for the current behavior is, that the server suggests us to disconnect (That's the "...+0" at the end.)
Actually, the problem changing this to let reconnecting be handled transparent is that the client needs to reauthenticate once again, which means the state of the current transport is lost. Reconnecting would cause a new onConnection() call on the server. Maybe the server sends some initial data which aren't expected in this state. This could cause problems.
Actually, what CAN be done is to change SocketIOException to take information about the server state. In onError() could be decided whether to reconnect or not on the base of this information. But reconnection in this state is at the application level.
so you are suggesting that I should change the code on IoEngine to
case IOMessage.TYPE_ERROR:
try {
findCallback(message).onError(
new SocketIOException(message.getData()));
} catch (SocketIOException e) {
error(e);
}
if (message.getData().endsWith("+0")) {
reconnect(); // adding this doesnt work
cleanup();
}
break;
I solved it!!
you just add handshake(); when it happens case IOMessage.TYPE_ERROR: try { findCallback(message).onError( new SocketIOException(message.getData())); } catch (SocketIOException e) { error(e); } if (message.getData().endsWith("+0")) {
handshake();
//cleanup();
}
break;
Hi @RedHotScalability:
Thanks for your investigation.
Unfortunally, this won't go upstream as this complicates the state machine.
For upstream users with this issue I suggest reestablishing the connection at application-level:
private static SocketIO socket;
static void main(String[] args) {
socket = new SocketIO( ... )
}
...
synchronized void onError(SocketIOException) {
this.socket = new SocketIO( ... )
}
(no guarantee for correctness ;)
Nevertheless, this error should not appear. socket.io-java-client shouldn't reestablish connections which are timed out. Can you provide a test case where this bug is triggered? This would be great :)
regards.
Hello there, I encountered the same problem I solved at application level forcing a reconnection with something like this:
OnError() {
socketClient = new SockeIO(....)
socketClient.connect()
}
Imho, this workaround should remain at application level. Maybe it could be helpful if socket.io-client can fire another differen exception/method handler for this particular case.
Hope this helps
I am having this same issue too, and fatshotty's fix works for reconnecting and continuing the program :) unfortunately, the signal I send to my node server that causes this error becomes lost, which I am trying to prevent.
The data from my Java client:
Aug 15, 2012 10:45:25 AM io.socket.IOConnection sendPlain
INFO: > 5:::{"args":["{\"message\":\"#StoryBehindMyScar a glass Christmas tree fell on my head after my sister shook the dresser. ?\",\"user\":\"alissaaaad\"}"],"name":"p5tweet"}
Aug 15, 2012 10:45:27 AM io.socket.IOConnection transportMessage
INFO: < 7:::1+0
io.socket.SocketIOException: 1+0
at io.socket.IOConnection.transportMessage(IOConnection.java:725)
at io.socket.WebsocketTransport.onMessage(WebsocketTransport.java:117)
at de.roderick.weberknecht.WebSocketReceiver.run(WebSocketReceiver.java:57)
Aug 15, 2012 10:45:27 AM io.socket.IOConnection cleanup
INFO: Cleanup
And how it shows up on my node server debug log:
debug - websocket received data packet 5:::{"args":["{\"message\":\"#StoryBehindMyScar a glass Christmas tree fell on my head after my sister shook the dresser.
info - transport end (undefined)
debug - set close timeout for client tNBZfNbhyzBYhJxmR3kP
debug - cleared close timeout for client tNBZfNbhyzBYhJxmR3kP
debug - cleared heartbeat interval for client tNBZfNbhyzBYhJxmR3kP
debug - discarding transport
debug - setting request GET /socket.io/1/websocket/tNBZfNbhyzBYhJxmR3kP
debug - set heartbeat interval for client tNBZfNbhyzBYhJxmR3kP
debug - websocket writing 7:::1+0
warn - client not handshaken client should reconnect
info - transport end (error)
debug - set close timeout for client tNBZfNbhyzBYhJxmR3kP
debug - cleared close timeout for client tNBZfNbhyzBYhJxmR3kP
debug - cleared heartbeat interval for client tNBZfNbhyzBYhJxmR3kP
debug - discarding transport
It seems like something in the string itself is causing the transport end to be undefined, which I figure is causing the error (maybe an odd character or something, they tend to show up as ??? in my java). I assume this is because the string is escaped or encoded wrong somehow, but I cannot figure out how. Is there something specific I should be doing with my strings before dumping them into a JSON object and sending them? If not already apparent, these strings are coming from twitter.
The string on the server side is truncated and therefor no valid JSON.
shook the dresser. ?\",\"user\":\"alissaaaad\"}"],"name":"p5tweet
Seems like the "?" is some other utf-8 character. What utf8-code does it represent?
I have not been able to figure that out. In every instance when I go to the actual tweet itself, that character has been replaced with blank space (you can see if you highlight where that character should be) https://twitter.com/alissaaaad/status/235794261260529664
I am assuming it is something outside of the utf-8 character set, or above a valid unicode threshold, because Japanese, Arabic, and other symbols have been able to pass through fine.
@gbatha Are you testing this on android?
I am not. My java client that sends the signal runs from the Processing IDE on my Mac OS 10.7 laptop.
I was able to determine the unicode for the characters in question! It seems to be a whole series of unicodes. On mac, in the character viewer, I was able to find this character set in the "Emoji" section. They seem to be graphical emoticons. Examples that have turned up are:
PURPLE HEART Unicode: U+1F49C (U+D83D U+DC9C), UTF-8: F0 9F 92 9C
WINKING FACE Unicode: U+1F609 (U+D83D U+DE09), UTF-8: F0 9F 98 89
OK HAND SIGN Unicode: U+1F44C (U+D83D U+DC4C), UTF-8: F0 9F 91 8C
edit: apparently github wouldn't even let me post this comment until the characters themselves were deleted from the post, haha. There must be some method of detecting these characters and preventing data from passing through. I am assuming adding that functionality to either the socket.io-java-client library or to my client application itself will fix the bug. Does anyone know how?
double edit: I think these are some kind of apple unicode, because the characters show up when I view them in safari but no other browser. http://twitter.com/fuccyoudis2o9/status/236370962512228355
I started a stack overflow topic and was able to fix the problem on the application side :) I am not sure if my fix is something that would be desired on the library side as it removes undesired utf8 characters from the string, but it does guarantee that these characters never end the transport.
I still don't have any idea why this happens.
I don't know if this might be related to this bug, but I'm having issues with my Android client. Every time the websocket is writing the value "7:::1+0", Android triggers the Garbage Collector, and the memory load increases to 60%-70% and the application gets unusable.
When I get this error, I proceed to reconnect:
public void reconnect() {
if(getReconnectThread() == null) {
_connected = false;
setReconnectThread(new Thread() {
public void run() {
while(!_connected) {
Log.e(TAG,"RECONNECT");
try {
_socket = null;
Log.e(TAG,"RECONNECT: Starting socket manager...");
SocketIOManager.this.start();
Log.e(TAG,"RECONNECT: new socket manager started. Sleeping now...");
Thread.sleep(5000);
Log.e(TAG,"RECONNECT: Woke up.");
} catch(InterruptedException ex) {
Log.e(TAG, "RECONNECT: Thread was interrupted");
} catch(Exception ex){
Log.e(TAG, "RECONNECT: Socket IOManager start() has thrown an exception: " + ex.getClass().toString());
}
}
}
});
getReconnectThread().start();
}
}
The reconnection is successful, and I can connect again to the server. However, the GC is triggered and does not stop.
I have tried to prevent reconnecting and reset the socket from the application layer. However, this does not prevent the GC to be triggered.
I am having the same problem as kikoso. Whenever the server disconnects the client, WebSocketClient gets stuck in an infinite loop at the line
while ( channel.isOpen() ) {
This causes the garbage collector to go crazy, giving rise to the GC_CONCURRENT messages shown above. When and if the client reconnects successfully, these messages continue, suggesting that there is a memory leak and that there is a thread still stuck in this infinite loop. I cannot work out the exact source of the problem myself. Could you please look into it?
Thanks
Hello, I have the same problem as SmallAxeApps and Kikoso. How can i fix it?
Thanks
We also facing this issue? Any good solutions for android out there?
this issue is related to multiple issues here, and still it is not fixed
I have the same issue as SmallAxeApps. Has anyone figured out how to fix this?
@datenstau I also had the same problem, but updating of java-websocket to version 1.3.0 fixed it for me
Issue is still happening for me as well. It is a major issue making the library unusable
Thankyou @lukas-hetzenecker . your solution worked for me
Hi, I met this problem too, using the suggestions in the comments above, this is how I fixed the problem, this is a small app I wrote to try the basic functionality of the library, I hope it's of any help:
public class MainActivity extends Activity {
private final static String TAG = "socketio";
private final static String URL = "http://192.168.43.200:1337/";
private SocketIO socket;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
IOCallback ioCallBack = new IOCallback() {
@Override
public void onMessage(JSONObject arg0, IOAcknowledge arg1) {
Log.d(TAG, "json message: " + arg0.toString());
}
@Override
public void onMessage(String arg0, IOAcknowledge arg1) {
Log.d(TAG, "string message: " + arg0);
}
@Override
public void onError(SocketIOException arg0) {
Log.d(TAG, "error: " + arg0.getMessage());
arg0.printStackTrace();
if (arg0.getMessage().endsWith("+0")) {
socket.disconnect();
try {
socket = new SocketIO(URL, this);
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
@Override
public void onDisconnect() {
Log.d(TAG, "disconnected");
}
@Override
public void onConnect() {
Log.d(TAG, "connected");
}
@Override
public void on(String arg0, IOAcknowledge arg1, Object... arg2) {
String message = "";
if (arg2.length > 0) {
for (int i = 0; i < arg2.length; i++) {
message += arg2[i].toString();
}
}
Log.d(TAG, "Event: " + arg0 + " payload: " + message);
}
};
try {
if (socket != null && !socket.isConnected()) {
socket = new SocketIO(URL, ioCallBack);
String[] args = {"sender_name", "message_text"};
socket.emit("my other event", (Object[]) args);
}
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
protected void onDestroy() {
socket.disconnect();
super.onDestroy();
}
This is the nodejs server code that I used. it's basically the code in the how to section in the socket.io web site:
var app = require('http').createServer(handler)
, io = require('socket.io').listen(app)
, fs = require('fs')
app.listen(1337);
function handler (req, res) {
fs.readFile(__dirname + '/index.html',
function (err, data) {
if (err) {
res.writeHead(500);
return res.end('Error loading index.html');
}
res.writeHead(200);
res.end(data);
});
}
io.sockets.on('connection', function (socket) {
io.sockets.emit('news', { will: 'be received by everyone'});
socket.on('my other event', function (from, msg) {
console.log('I received a private message by ', from, ' saying ', msg);
});
socket.on('disconnect', function () {
io.sockets.emit('user disconnected');
});
});
A Million Thanks @lukas-hetzenecker . I tried to fix the same bug for one week, finallly upgrading to 1.3 saved my ass
Library works fine, you need check server side
Hi Sandro, This issue solved but, we are going to native socket implementation on the server side, we not using socket.io on the server side and client not used any library, too.
On Fri, Jan 15, 2016 at 5:57 AM, Sandro Simas notifications@github.com wrote:
This issue was solved? I think i'm having problem with this in my Android app.
— Reply to this email directly or view it on GitHub https://github.com/Gottox/socket.io-java-client/issues/4#issuecomment-171832720 .
debug: set close timeout for client 438823659631090974 debug: cleared close timeout for client 438823659631090974 debug: cleared heartbeat interval for client 438823659631090974 debug: discarding transport debug: setting request GET /socket.io/1/websocket/438823659631090974 debug: set heartbeat interval for client 438823659631090974 debug: websocket writing 7:::1+0 warn: client not handshaken client should reconnect info: transport end (error)
To generate this launch node.js + socket.io. Connect a client (socket.io-java-client) to the server. Restart node.js (with socket.io ofc) and you will see the error.
Obviously there should be a way to detect when the websocket is writing 7:::1+0, and when it occurs the client should disconnect the socket and reconnect.