【问题标题】:Node.js and Websocket in Android EclipseAndroid Eclipse 中的 Node.js 和 Websocket
【发布时间】:2015-03-31 23:06:07
【问题描述】:

感谢您调查我的问题。

我是 android 开发的初学者,目前我正在尝试制作使用 socket 和 node js 的聊天应用程序。

我使用了来自 github 的库,即 https://github.com/Gottox/socket.io-java-client,并且能够向我的服务器发送消息,并且我还能够在“new_client_message”下接收回消息,如下面的 logcat 图像所示。

我面临的问题是我无法弄清楚从服务器获取消息以将其显示在列表视图中的方法。如果有人可以帮助我,那就太好了。提前致谢

我的 LogCat:

Node.js 代码:

var socket = require('socket.io');
var express = require('express');
var http = require('http');

var app = express();
var server = http.createServer(app);

var io = socket.listen(server);

var users = {};
var clients = {};

io.sockets.on( 'connection', function(socket) {
console.log("New client !");
var socket_id = socket.id;
var hs = socket.handshake;
//store user with socket id
if(hs.query.user_id !== undefined){
    users[hs.query.user_id] = socket.id; // connected user with its     socket.id

}

clients[socket.id] = socket; // add the client data to the hash

socket.on('disconnect', function () {
    delete clients[socket.id]; // remove the client from the array
    delete users[hs.query.username]; // remove connected user & socket.id
});

socket
    .on('new_message', function(data){
        clients[users['admin']].emit('new_message', {'original_data':data,'socket_id': socket_id } );
    })
    .on('new_client_message', function(data){
        console.log(data);
        clients[data.socket_id].emit('new_client_message', data.message);
    })
;

});

server.listen(3030);

这是我的代码:

socket = null;
    try {
        socket = new SocketIO("http://xxx.xxx.xx.xx:3030/");
    } catch (MalformedURLException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }
    socket.connect(new IOCallback() {
        @Override
        public void onMessage(JSONObject json, IOAcknowledge ack) {
            try {
                System.out.println("Server said:" + json.toString(2));
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onMessage(String data, IOAcknowledge ack) {
            System.out.println("Server said: " + data);

        }

        @Override
        public void onError(SocketIOException socketIOException) {
            System.out.println("an Error occured");
            socketIOException.printStackTrace();
        }

        @Override
        public void onDisconnect() {
            System.out.println("Connection terminated.");
        }

        @Override
        public void onConnect() {
            System.out.println("Connection established");
        }

      //here I was trying to get the message from the server, convert into string and 
      //display in list view(thats when the error displayed)

        @Override
        public void on(String event, IOAcknowledge ack, Object... args) {
            System.out.println("Server triggered event '" + event + "'");
            System.out.println("senrver ack" + ack);
            System.out.println("server said this " + args[0]);

            rohan = args[0].toString();


            mListData.add(rohan);
            //mListData.add(args[0].toString());

        }


    });

    //mListData.add(rohan);

  //sending the message from the app when onclick to the server which is sucessful

    send.setOnClickListener(new OnClickListener(){

        @Override
        public void onClick(View arg0) {
            // TODO Auto-generated method stub


            // This line is cached until the connection is establisched.
            //socket.send("new_message");



            chat = messag.getText().toString();

            karan = client_email+";"+chat;

         // This line is cached until the connection is establisched.
            socket.emit("new_message", karan);
            click();




        }

        private void click() {
            // TODO Auto-generated method stub
            //getting the username
            name = getIntent().getExtras().getString("name");
            String output = name.substring(0,1).toUpperCase() + name.substring(1);


            // converting the TextView message to string
            msg = messag.getText().toString();

            // combining the username and the text view
            messag.setText(output +" " + ":" + " " + msg);

            //showing the final combination in the listview
            mListData.addAll(messag.getText().toString());

            messag.setText("");

            //when the list view is updated with data, then it goes to that position
            lvList.setSelection(mListData.getCount() -1);
            post();

        }

请指导我应该在哪里添加更多代码以在列表视图中显示来自 node.js 服务器的消息。我确信我犯了一些错误,如果有人能纠正我,我将不胜感激。 非常感谢!

【问题讨论】:

  • 我很困惑这里的问题是什么,你说你可以给服务器发消息,服务器可以发回消息,那么有什么问题吗?为了从服务器获取消息,服务器需要通过套接字发送这些消息(就像使用 hello 消息一样)。
  • @Epicblood 感谢您花时间研究我的问题。是的,我可以从我的服务器收到一条消息。我在这里面临的主要问题是在我的应用程序中显示该消息。即在 ListView 中。谢谢
  • 只需将其添加到任何保存列表视图数据的位置,然后在适配器上调用 notifyDataSetChanged() 以更新列表
  • @Epicblood 我已经添加了“mListData.add(rohan);”在我的代码中,如上所示,还添加了“mListData.notifyDataSetChanged();”之后更新列表。这里“mListData”是我的数组适配器,“rohan”是存储来自服务器的消息的字符串。还是行不通。如果我执行“system.out.println(rohan)”,那么我可以在我的 logcat 中看到来自服务器的消息,但我无法在我的应用程序中显示它。

标签: java android eclipse node.js websocket


【解决方案1】:

Hy Karan.. 你走对了,伙计。唯一缺少的是代码的小sn-p。这里的错误是您在工作线程中设置了适配器。您只能从主线程更新视图。 您必须将更新 ui 的后台任务部分移动到主线程上。 只需将代码替换为:

@Override
            public void on(String event, IOAcknowledge ack, Object... args)

与:

@Override
            public void on(String event, IOAcknowledge ack, Object... args) {
                // TODO Auto-generated method stub
                if(event.equals("new_client_message")){
                    Log.v("SocketIO", "new_client_message" + " " + args[0]);
                    rohan = args[0].toString();
                    System.out.println("admin" + " : " + " " + rohan);

                    runOnUiThread(new Runnable(){

                        @Override
                        public void run() {
                            // TODO Auto-generated method stub
                            mListData.add("Admin" + " : " + " " + rohan);
                            mListData.notifyDataSetChanged();
                            lvList.setSelection(mListData.getCount() -1);

                        }

                    });
                }

这里的“new_client_message”是从服务器触发的.. 只需替换为您的。 例如,在您的情况下,“new_message”是从您的应用程序到服务器的触发器。对不起,不是一个专业的词,但我希望它会有所帮助。 干杯

【讨论】:

  • 哇......真的......像魅力一样工作。非常感谢你。我非常渴望让我的应用程序正常运行,你在这里……你太棒了。
  • 别担心,伙计。毕竟,建立和培养关系——以及回馈——是 stackoverflow 的基石。
猜你喜欢
  • 1970-01-01
  • 2011-06-08
  • 1970-01-01
  • 2015-01-16
  • 1970-01-01
  • 2011-12-30
  • 2014-07-26
  • 2016-08-25
  • 2019-11-06
相关资源
最近更新 更多