nowelium / socket.io-titanium

socket.io for titanium mobile
http://youtu.be/10ogNjWCpyc
Other
136 stars 34 forks source link

Messages >= 48 Chars Breaks the Connection #8

Closed allenhartwig closed 12 years ago

allenhartwig commented 12 years ago

If I emit a message from the client to the server with a message length greater than 48 characters the connection breaks with a server message of:

websocket parser error: reserved fields must be empty or websocket parser error: no handler for opcode #

There seems to be no client-side error triggered on this event.

I am using the Titanium Mobile v1.8.1 SDK with Socket.IO v.8.

Any thoughts on how to resolve?

nowelium commented 12 years ago

https://gist.github.com/1768174 (sorry japanese) probably can be resolve with this patch. please apply to patch(ti-websocket-client.js)

allenhartwig commented 12 years ago

Thanks Yusuke. That took care of the 48char limit, however I am now up against another limit.

On the client, I am receiving this error:

line = 949;
message = "Offset 65536 is past buffer bounds (length 65536).   in -[CodecModule encodeNumber:] (CodecModule.m:64)";
sourceId = 284287168;
sourceURL = "";

For reference, I am trying to upload a base64 encoded image over the socket.

nowelium commented 12 years ago

Thank you for report.

BUFFER_SIZE (65536) is ti-websocket-client defined Ti.Buffer defaults size. I'm testing now. to fix this problem.

It turned out that it is avoidable by another approach(i think it is not so very well)

var listenSocket = io.connect('...');
var uploadSocket = io.connect('....', {
  transports: ['xhr-polling'],
  'force new connection': true
});
uploadSocket.emit('upload', { base64: ..... })
listenSocket.on('foo', function(e){...});

Please wait a little until resolution

nowelium commented 12 years ago

Hi allenhartwig.

I'm just implementation for fragmentation packet send (http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-07#section-4.4) please try afeaf461fc3410c5dfe65cd52d35b480a6e1ba74 or lastest master branch

allenhartwig commented 12 years ago

Yusuke,

This worked great for the upload, however, when I pull the data back down from the server I am getting this error:

[ERROR] TiBoundsException. Offset 68056 is past buffer bounds (length 65536)  in -[TiBuffer copy:] (TiBuffer.m:176)
[WARN] Exception in event callback. {
    line = 495;
    message = "TiBoundsException. Offset 68056 is past buffer bounds (length 65536)  in -[TiBuffer copy:] (TiBuffer.m:176)";
    sourceId = 292429920;
    sourceURL = "";
}
nowelium commented 12 years ago

Hi allenhartwig,

I had a similar problem. try this patch.

--- a/Resources/ti-websocket-client/ti-websocket-client.js
+++ b/Resources/ti-websocket-client/ti-websocket-client.js
@@ -1069,9 +1069,10 @@ WebSocket.prototype._read_callback = function(e) {
                        this.buffer = this._socketReadBuffer.clone();
                        this.bufferSize = e.bytesProcessed;
                }
-               else {
-                       this.buffer.copy(this._socketReadBuffer, this.bufferSize, 0, e.bytesProcessed);
-                       this.bufferSize += e.bytesProcessed;
+    else {
+      this.buffer.copy(this._socketReadBuffer, this.bufferSize, 0, e.bytesProcessed);
+      this.bufferSize += e.bytesProcessed;
+      this.buffer.length += e.bytesProcessed;
                        this._socketReadBuffer.clear();
                }
        }

a series of problem pull requested ti-websocket-client(https://github.com/masuidrive/ti-websocket-client/pull/3)

allenhartwig commented 12 years ago

This seems to solve the problem for smaller uploads, however, if performing a larger transfer, the heartbeat times out and the server drops the connection. I'm guessing if the upload takes more than 15seconds, the connection is terminated. Is there any way to keep the heartbeat alive during the upload?

For reference, I am attempting to upload a image grabbed from the camera, scaled to 640x640, encoded in base64.

nowelium commented 12 years ago

umm...

Keep the heartbeat during sending is difficult on the current websocket implementation. added property of FRAGMENT_SIZE ....

io.titanium.FRAGMENT_SIZE = 524288;                                      
var socket = io.connect(...);

this code is available in the latest master branch.

However, it seems to be better to give up upload of base64. I recommend you XHR upload.

allenhartwig commented 12 years ago

Thanks for your help.