Pergunta

I'm working with Titanium SDK 3.1.3 and trying to build an application with a chat that connects to a node js server. So far I've tried two different modules to do this, but haven't had any luck with both of them. The first module I've tried was socket.io-titanijm, my code for it looks like this:

var io = require('socket.io-titanium');
    var socket = io.connect('IP:PORT', {'force new connection':true});
    socket.on('connect', function() 
    {
        // Connected, let's sign-up for to receive messages for this room
        Ti.API.info('connected to socket');
        socket.emit('room', conversationId.toString());
    });

    socket.on('messageReceived', function(data) 
    {
        Ti.API.info('message received');

        try {
            addMessageFromNode(data);
        } catch(e) {
            alert(e);
        }

    });

But I get the error:

E/TitaniumModule(19374): Invalid value, expected type Number.
E/V8Exception(19374): Exception occurred at ti:/bootstrap.js:131: Uncaught Error: Invalid value, expected type Number.
E/XMLModule(19374): (KrollRuntimeThread) [1450,1450] Error parsing XML
E/XMLModule(19374): org.xml.sax.SAXParseException: Unexpected token (position:TEXT faa_rzQcGIc9Vzvt...@1:72 in java.io.InputStreamReader@411485a8) 
E/XMLModule(19374):     at org.apache.harmony.xml.parsers.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:146)
E/XMLModule(19374):     at javax.xml.parsers.DocumentBuilder.parse(DocumentBuilder.java:107)
E/XMLModule(19374):     at ti.modules.titanium.xml.XMLModule.parse(XMLModule.java:82)
E/XMLModule(19374):     at ti.modules.titanium.xml.XMLModule.parse(XMLModule.java:68)
E/XMLModule(19374):     at ti.modules.titanium.network.TiHTTPClient.getResponseXML(TiHTTPClient.java:655)
E/XMLModule(19374):     at ti.modules.titanium.network.HTTPClientProxy.getResponseXML(HTTPClientProxy.java:93)
E/XMLModule(19374):     at org.appcelerator.kroll.runtime.v8.V8Object.nativeCallProperty(Native Method)
E/XMLModule(19374):     at org.appcelerator.kroll.runtime.v8.V8Object.callProperty(V8Object.java:69)
E/XMLModule(19374):     at org.appcelerator.kroll.KrollProxy.handleMessage(KrollProxy.java:1098)
E/XMLModule(19374):     at android.os.Handler.dispatchMessage(Handler.java:95)
E/XMLModule(19374):     at android.os.Looper.loop(Looper.java:137)
E/XMLModule(19374):     at org.appcelerator.kroll.KrollRuntime$KrollRuntimeThread.run(KrollRuntime.java:112)
E/TiHttpClient(19374): (KrollRuntimeThread) [5,1455] Error parsing XML
E/TiHttpClient(19374): org.xml.sax.SAXParseException: Unexpected token (position:TEXT faa_rzQcGIc9Vzvt...@1:72 in java.io.InputStreamReader@411485a8) 
E/TiHttpClient(19374):  at org.apache.harmony.xml.parsers.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:146)
E/TiHttpClient(19374):  at javax.xml.parsers.DocumentBuilder.parse(DocumentBuilder.java:107)
E/TiHttpClient(19374):  at ti.modules.titanium.xml.XMLModule.parse(XMLModule.java:82)
E/TiHttpClient(19374):  at ti.modules.titanium.xml.XMLModule.parse(XMLModule.java:68)
E/TiHttpClient(19374):  at ti.modules.titanium.network.TiHTTPClient.getResponseXML(TiHTTPClient.java:655)
E/TiHttpClient(19374):  at ti.modules.titanium.network.HTTPClientProxy.getResponseXML(HTTPClientProxy.java:93)
E/TiHttpClient(19374):  at org.appcelerator.kroll.runtime.v8.V8Object.nativeCallProperty(Native Method)
E/TiHttpClient(19374):  at org.appcelerator.kroll.runtime.v8.V8Object.callProperty(V8Object.java:69)
E/TiHttpClient(19374):  at org.appcelerator.kroll.KrollProxy.handleMessage(KrollProxy.java:1098)
E/TiHttpClient(19374):  at android.os.Handler.dispatchMessage(Handler.java:95)
E/TiHttpClient(19374):  at android.os.Looper.loop(Looper.java:137)
E/TiHttpClient(19374):  at org.appcelerator.kroll.KrollRuntime$KrollRuntimeThread.run(KrollRuntime.java:112)

I have no idea where this bootstrap.js file is at all, such file doesn't exist in my project so I believe this is a file in Titanium SDK?. The other module I've tried to use was iamyellow's tiws module, for which I used the following code:

var ws = require('net.iamyellow.tiws').createWS();
    ws.addEventListener('open', function() {
        Ti.API.info('websocket opened');
    });

    ws.addEventListener('close', function(ev) {
        Ti.API.info('close');
        Ti.API.info(ev);
    });

    ws.addEventListener('error', function(ev) {
        Ti.API.info('error');
        Ti.API.info(ev);
    });

    ws.addEventListener('message', function(ev) {
        Ti.API.info('message');
        Ti.API.info(ev);
    });

    ws.open('IP:PORT');

But this module doesn't even connect at all, no error message is thrown, I've checked logcat throughly while testing this module and didn't find anything. Do these modules not work with Titanium SDK 3.x? If they do, then what is going on? Both are labeled as "easy to implement" but the documentation on both is quite bad and the behavior displayed is quite confusing.

Foi útil?

Solução

Ok, this one was a little bit tricky, but after going through several tickets I read that there's an issue with timeouts on Android. If the variable you're assigning to the timeout isn't defined, then it won't work. What I mean is, if you have something like;

this.timeoutTimer = setTimeout(...); //imagine the variable this is a reference to an object that is storing properties for a connection.

it won't work, but if you give a null value to the timeoutTimer property before assigning it the timeout id like this:

this.timeoutTimer = null;
.
. doing something else
.
this.timeoutTimer = setTimeout(...);

it will work with no problem.

Take note on this, THIS IS AN ANDROID ISSUE ONLY, iOS DOESN'T PRESENT THIS ISSUE BUT IF YOU'RE CROSS-PLATFORMING THEN MAKE SURE ANY VARIABLE THAT WILL STORE A TIMEOUT ID IS INITIALIZED AS NULL FIRST.

Now to solve my question, you must be using the socket.io-titanium module, I couldn't make the tiws module to work. So here are the steps to fix this issue using socket.io-titanium:

  1. Go to the socket.io folder in your folder, then open the lib folder, here there will be several javascript files.
  2. Open the socket.js file.
  3. Search for the line Socket.prototype.handshake = function (fn)
  4. Add the line this.heartbeatTimeoutTimer = null; just below the previous line.
  5. Save and compile for Android.

Now this should make the connection work.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top