Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android get an Error while connection to Socket

i'm trying to write simple application with nodejs and express.io after reading some express.io document and successful connection to http://chat.socket.io i'm find simple sample for create server side with nodejs and express.io, after run this below code in command line and opening http://localhost:3000 in browser i dont get any error, i can not find any good document about coding in http://chat.socket.io server, now i want to try send request from android client to server with samples, but i get connection error:

Error:

CONNECTION ERROR

server.js:

// Setup basic express server
var express = require('express');
var app = express();
var server = require('http').createServer(app);
var io = require('../..')(server);
var port = process.env.PORT || 3000;

server.listen(port, function () {
  console.log('Server listening at port %d', port);
});

// Routing
app.use(express.static(__dirname + '/public'));

// Chatroom

// usernames which are currently connected to the chat
var usernames = {};
var numUsers = 0;

io.on('connection', function (socket) {
  var addedUser = false;

  // when the client emits 'new message', this listens and executes
  socket.on('new message', function (data) {
    // we tell the client to execute 'new message'
    socket.broadcast.emit('new message', {
      username: socket.username,
      message: data
    });
  });

  // when the client emits 'add user', this listens and executes
  socket.on('add user', function (username) {
    // we store the username in the socket session for this client
    socket.username = username;
    // add the client's username to the global list
    usernames[username] = username;
    ++numUsers;
    addedUser = true;
    socket.emit('login', {
      numUsers: numUsers
    });
    // echo globally (all clients) that a person has connected
    socket.broadcast.emit('user joined', {
      username: socket.username,
      numUsers: numUsers
    });
  });

  // when the client emits 'typing', we broadcast it to others
  socket.on('typing', function () {
    socket.broadcast.emit('typing', {
      username: socket.username
    });
  });

  // when the client emits 'stop typing', we broadcast it to others
  socket.on('stop typing', function () {
    socket.broadcast.emit('stop typing', {
      username: socket.username
    });
  });

  // when the user disconnects.. perform this
  socket.on('disconnect', function () {
    // remove the username from global usernames list
    if (addedUser) {
      delete usernames[socket.username];
      --numUsers;

      // echo globally that this client has left
      socket.broadcast.emit('user left', {
        username: socket.username,
        numUsers: numUsers
      });
    }
  });
});

my android code:

private Socket mSocket;
{
    try {
        /* connection successful to http://chat.socket.io */
        mSocket = IO.socket("http://localhost:3000");
    } catch (URISyntaxException e) {
        Log.e("Error URI", String.valueOf(e));
        throw new RuntimeException(e);
    }
}
public void onCreate(Bundle savedInstanceState) {
    ...
    mSocket.on(Socket.EVENT_CONNECT_ERROR, onConnectError);
    mSocket.on(Socket.EVENT_CONNECT_TIMEOUT, onConnectError);
    mSocket.on("new message", onNewMessage);
    mSocket.on("user joined", onUserJoined);
    mSocket.on("user left", onUserLeft);
    mSocket.on("typing", onTyping);
    mSocket.on("stop typing", onStopTyping);
    mSocket.connect();
    ...

    Button signInButton = (Button) findViewById(R.id.sign_in_button);
    signInButton.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View view) {
            attemptLogin();
        }
    });

    mSocket.on("login", onLogin);
}

private void attemptLogin() {
    mUsernameView.setError(null);
    String username = mUsernameView.getText().toString().trim();
    if (TextUtils.isEmpty(username)) {
        mUsernameView.setError(getString(R.string.error_field_required));
        mUsernameView.requestFocus();
        return;
    }

    mUsername = username;
    mSocket.emit("add user", username);
}

Android Error:

E/AndroidRuntime﹕ FATAL EXCEPTION: EventThread
    java.lang.IllegalArgumentException: delay < 0: -432345566375051264
            at java.util.Timer.schedule(Timer.java:457)
            at com.github.nkzawa.socketio.client.Manager.reconnect(Manager.java:497)
            at com.github.nkzawa.socketio.client.Manager.access$2000(Manager.java:20)
            at com.github.nkzawa.socketio.client.Manager$8$1$1.call(Manager.java:519)
            at com.github.nkzawa.socketio.client.Manager$1$3.call(Manager.java:282)
            at com.github.nkzawa.emitter.Emitter.emit(Emitter.java:117)
            at com.github.nkzawa.engineio.client.Socket.onError(Socket.java:754)
            at com.github.nkzawa.engineio.client.Socket.access$800(Socket.java:29)
            at com.github.nkzawa.engineio.client.Socket$4.call(Socket.java:293)
            at com.github.nkzawa.emitter.Emitter.emit(Emitter.java:117)
            at com.github.nkzawa.engineio.client.Transport.onError(Transport.java:63)
            at com.github.nkzawa.engineio.client.transports.PollingXHR.access$100(PollingXHR.java:19)
            at com.github.nkzawa.engineio.client.transports.PollingXHR$6$1.run(PollingXHR.java:126)
            at com.github.nkzawa.thread.EventThread$2.run(EventThread.java:75)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
            at java.lang.Thread.run(Thread.java:838)
like image 798
DolDurma Avatar asked Sep 18 '26 06:09

DolDurma


1 Answers

I would blame this:

mSocket = IO.socket("http://localhost:3000");

I assume you are not running your node.js server on your android, but probably on your PC. If so, when testing on your android, you are trying to connect back on port 3000 to your android itself - as localhost links to device itself.

If you are using the same local network on your server and android, you should check your PC's IP and put it instead of localhost. If your server has public IP, you may want to use it instead.


edit

1

In other words, according to your comment: your PC IP is 192.168.1.5. As this is an internal IP, your android have to be connected to same sub-network your PC is, just because youre able to occur your connectin error. Basing to that, i assume you need to type http://192.168.1.5/ in adress bar in your android, to visit page your PC is serving. Assuming that, one remains nonchanged - the script "my android code" is running on your android. So instead of localhost there is required a proper host: 192.168.1.5. Cant tell if your android is blocking 3000 port, but localhost is improper from androids' point of view, as long as you are not running your nodejs server on that device.

Also that change may not take affect ad-hoc, during browser cache on mobile devices.

2

Looking into your code, I assume you will also occur some problems with users using same username. Yeah, sounds strange, but users may want to open few tabs in browser, connected to same socket server. Once that, your usernames and numUsers variables will corrupt.

As long as app is single-intance dedicated (eg. player@game), I would use

usernames[username] = socket

to store sockets aside, being able to post cross-player related events avoiding iteration over all opened sockets.

Also for chat-purposes, you may want to allow users being connected on few browser tabs at once. Usually I'm storing all sockets just this way:

if (!users[user]) {
    users[user] = {
        sockets: [socket]
    };
    console.log(sprintf('[%s] [CONNECTED] User %s', Date(), user));

} else {
    users[user].sockets.push(socket);
}

your may be different, prolly based on chat-channels etc. Pushing sockets aside listeners allowed me to run separate UDP server in same node script file. It was in purpose of being able to monit/block/alert single user through all opened tabs, event if their are spread over two different browsers.

like image 164
yergo Avatar answered Sep 20 '26 18:09

yergo



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!