【问题标题】:Android get an Error while connection to SocketAndroid 在连接到 Socket 时出现错误
【发布时间】:2015-02-27 11:19:32
【问题描述】:

在阅读了一些 express.io 文档并成功连接到http://chat.socket.io 之后,我正在尝试使用 nodejs 和 express.io 编写简单的应用程序,我在运行后找到了使用 nodejs 和 express.io 创建服务器端的简单示例以下代码在命令行中并在浏览器中打开http://localhost:3000 我没有收到任何错误,我在http://chat.socket.io 服务器中找不到任何关于编码的好文档,现在我想尝试从android客户端发送请求到带有示例的服务器,但是我收到连接错误:

错误:

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
      });
    }
  });
});

我的安卓代码:

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 错误:

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)

【问题讨论】:

  • 您的服务器端不是在监听端口号 7076 吗?客户端正在尝试连接到端口 3000。我不确定,但这可能是个问题。
  • @jonDoe 我忘记在粘贴代码后进行编辑先生,我的问题不是端口
  • @jonDoe 帖子已更新,先生,请查看

标签: android node.js express


【解决方案1】:

我会责备这个:

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

我假设您没有在您的 android 上运行 node.js 服务器,但可能在您的 PC 上。如果是这样,在您的 android 上进行测试时,您会尝试在端口 3000 上重新连接到您的 android 本身 - 因为localhost 链接到设备本身。

如果您在服务器和安卓上使用相同的本地网络,您应该检查您的 PC 的 IP 并将其放入而不是 localhost。如果您的服务器有公共 IP,您可能希望使用它。


编辑

1

也就是说,根据您的评论:您的PC IP 是192.168.1.5。由于这是一个内部 IP,因此您的 android 必须连接到您的 PC 所在的同一子网,因为您可能会发生连接错误。基于此,我假设您需要在 android 的地址栏中输入http://192.168.1.5/,才能访问您的 PC 正在服务的页面。假设,一个保持不变 - 脚本“我的 android 代码”正在你的 android 上运行。所以需要一个合适的主机而不是localhost192.168.1.5。无法判断您的 android 是否阻塞了 3000 端口,但从 android 的角度来看,localhost 是不合适的,只要您不在该设备上运行 nodejs 服务器。

此外,在移动设备上的浏览器缓存期间,该更改可能不会临时影响。

2

查看您的代码,我假设您也会遇到使用相同用户名的用户的一些问题。是的,听起来很奇怪,但用户可能想在浏览器中打开几个选项卡,连接到同一个套接字服务器。一旦那样,您的 usernamesnumUsers 变量将损坏。

只要应用是单实例专用的(例如 player@game),我就会使用

usernames[username] = socket

将套接字存储在一边,能够发布跨玩家相关事件,避免对所有打开的套接字进行迭代。

此外,出于聊天目的,您可能希望允许用户同时在几个浏览器选项卡上进行连接。通常我都是这样存储所有套接字的:

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

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

你可能会有所不同,基于聊天频道等。将套接字推到一边,让我可以在同一个节点脚本文件中运行单独的 UDP 服务器。其目的是能够通过所有打开的选项卡监控/阻止/警告单个用户,如果它们分布在两个不同的浏览器上。

【讨论】:

  • @Mahdi.Pishguy 我同意这一点。
  • @yergo Nodejs 服务器正在运行,我对此没有任何问题,我的电脑的 ip 是 192.168.1.5,更新后没有任何变化,localhost192.168.1.5 他们都是我在连接错误时也是如此。
  • @Mahdi.Pishguy 扩展了我的答案。希望对您有所帮助
  • @yergo 谢谢先生,我的问题解决了 :) 我可以在其他问题上寻求帮助吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-19
  • 2020-04-04
  • 1970-01-01
  • 2020-08-22
  • 2019-06-21
  • 1970-01-01
相关资源
最近更新 更多