Android应用程序使用Socket.io连接到Node.js服务器

我无法让我的Android应用连接到socket.io聊天服务器。 我使用Gottox创build的socket.io-java-client,可以在这里find: https : //github.com/Gottox/socket.io-java-client

服务器通过端口7000本地运行。我正在使用android模拟器,所以我使用10.0.2.2:7000来访问服务器。

任何帮助将不胜感激,我没有太多的SSL经验。 如果我find一个工作解决scheme,我也会发布它。

Node.js服务器

var express = require('express'); var app = express(); var server = require('http').createServer(app).listen(7000); var io = require('socket.io').listen(server); io.sockets.on('connection', function(client){ client.on('message', function(err, msg){ client.broadcast.emit('message', msg); }); }); 

的package.json

 { "name": "simplechat", "version": "0.0.1", "main": "app.js", "dependencies": { "express" : "~4.0.0", "socket.io" : "~0.9.13" } } 

Android:SendMessageActivity

 public class SendMessageActivity extends Activity { private static final String SERVER_ADDRESS = "https://10.0.2.2:7000"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_send_message); System.out.println("Sever: " + SERVER_ADDRESS); try { SocketIO socket = new SocketIO(new URL(SERVER_ADDRESS), new IOCallback() { @Override public void onDisconnect() { System.out.println("disconnected"); } @Override public void onConnect() { System.out.println("connected"); } @Override public void onMessage(String s, IOAcknowledge ioAcknowledge) { } @Override public void onMessage(JSONObject jsonObject, IOAcknowledge ioAcknowledge) { } @Override public void on(String event, IOAcknowledge ioAcknowledge, Object... objects) { } @Override public void onError(SocketIOException e) { e.printStackTrace(); } }); } catch (MalformedURLException ex) { ex.printStackTrace(); } } 

Android权限

 <uses-permission android:name="android.permission.INTERNET"> </uses-permission> 

错误代码

 08-09 16:07:28.224 8411-8441/com.example.puma.chatexample W/System.err﹕ io.socket.SocketIOException: Error while handshaking 08-09 16:07:28.225 8411-8441/com.example.puma.chatexample W/System.err﹕ at io.socket.IOConnection.handshake(IOConnection.java:322) 08-09 16:07:28.225 8411-8441/com.example.puma.chatexample W/System.err﹕ at io.socket.IOConnection.access$600(IOConnection.java:39) 08-09 16:07:28.225 8411-8441/com.example.puma.chatexample W/System.err﹕ at io.socket.IOConnection$ConnectThread.run(IOConnection.java:199) 08-09 16:07:28.226 8411-8441/com.example.puma.chatexample W/System.err﹕ Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'javax.net.ssl.SSLSocketFactory javax.net.ssl.SSLContext.getSocketFactory()' on a null object reference 08-09 16:07:28.226 8411-8441/com.example.puma.chatexample W/System.err﹕ at io.socket.IOConnection.handshake(IOConnection.java:302) 08-09 16:07:28.227 8411-8441/com.example.puma.chatexample W/System.err﹕ ... 2 more 

我真的解决了这个问题。 我用我的电脑的本地IP http://192.168.0.xxx:7000和应用程序能够连接到模拟器的聊天服务器&#x3002; 我不知道为什么这个工作,但它可能会帮助未来的人:)

更新:

这就是我最终完成项目的结构。 我创build了一个单例类来处理Android端的套接字连接(你也可以把它作为一个服务)。 当接收到消息时,单例类向应用程序的其余部分广播意图。 然后在相关活动中由广播接收机接收意图。

Android侧(单身人士):

 public class SocketSingleton { private static SocketSingleton instance; private static final String SERVER_ADDRESS = "http://1.2.3.4:1234"; private SocketIO socket; private Context context; public static SocketSingleton get(Context context){ if(instance == null){ instance = getSync(context); } instance.context = context; return instance; } public static synchronized SocketSingleton getSync(Context context){ if (instance == null) { instance = new SocketSingleton(context); } return instance; } public SocketIO getSocket(){ return this.socket; } private SocketSingleton(Context context){ this.context = context; this.socket = getChatServerSocket(); this.friends = new ArrayList<Friend>(); } private SocketIO getChatServerSocket(){ try { SocketIO socket = new SocketIO(new URL(SERVER_ADDRESS), new IOCallback() { @Override public void onDisconnect() { System.out.println("disconnected"); } @Override public void onConnect() { System.out.println("connected"); } @Override public void on(String event, IOAcknowledge ioAcknowledge, Object... objects) { if (event.equals("chatMessage")) { JSONObject json = (JSONObject) objects[0]; ChatMessage chatMessage = new ChatMessage(json); Intent intent = new Intent(); intent.setAction("newChatMessage"); intent.putExtra("chatMessage", chatMessage); context.sendBroadcast(intent); } } @Override public void onError(SocketIOException e) { e.printStackTrace(); } }); return socket; } catch (MalformedURLException ex) { ex.printStackTrace(); } return null; } } 

Android侧(活动):

 public class ChatActivity extends Activity { super.onCreate(savedInstanceState); setContentView(R.layout.activity_chat); IntentFilter newChatMessageFilter = new IntentFilter("newChatMessage"); this.registerReceiver(new MessageReceiver(), newChatMessageFilter); ... public class MessageReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent){ final ChatMessage chatMessage =(ChatMessage) intent.getExtras().get("chatMessage"); runOnUiThread(new Runnable() { @Override public void run() { mAdapter.add(chatMessage); mAdapter.notifyDataSetChanged(); } }); } } } 

服务器端:

 var express = require('express'); var app = express(); var server = require('http').createServer(app).listen(1234); var io = require('socket.io').listen(server); io.sockets.on('connection', function(client){ console.log("client connected: " + client.id); client.on("sendTo", function(chatMessage){ console.log("Message From: " + chatMessage.fromName); console.log("Message To: " + chatMessage.toName); io.sockets.socket(chatMessage.toClientID).emit("chatMessage", {"fromName" : chatMessage.fromName, "toName" : chatMessage.toName, "toClientID" : chatMessage.toClientID, "msg" : chatMessage.msg}); }); }); 

我知道这不是OP的post真正的答案,但是对于那些可能感兴趣的人来说,这是一个教程,我使用Node.js服务器来与你的Android进行通信 – 没有任何额外的库

https://causeyourestuck.io/2016/04/27/node-js-android-tcpip/

这是最后看起来如何的预测:

 Client socket = new Client("192.168.0.8", 1234); socket.setOnEventOccurred(new Client.OnEventOccurred() { @Override public void onMessage(String message) { } @Override public void onConnected(Socket socket) { socket.send("Hello World!"); socket.disconnect(); } @Override public void onDisconnected(Socket socket, String message) { } }); socket.connect(); 

我听说你是模拟器networking,与你的PC不一样。 所以,如果你可以通过改变尝试在一个实际的电话连接到您的PC相同的networking。

您可能无法从您的模拟器ping 10.0.2.2 ,或者从您的PC到仿真器的其他方式。

Puma已经对如何使用SocketIO实现套接字连接进行了回答。 这没什么新贡献。 然而,这是一个帮助新手的尝试,同时也介绍了Socket.io的java库的实现。

Socket.IO在Github上有它自己的java实现,你可以按照它来创build一个Android / Java套接字应用程序。

Android方面:

把它包含在你的build gradle中

 compile ('io.socket:socket.io-client:0.8.3') { // excluding org.json which is provided by Android exclude group: 'org.json', module: 'json' } 

在您的应用中提供权限

 <uses-permission android:name="android.permission.INTERNET" /> 

Android代码:代码结构与Node中的代码类似。 socket.on中的消息类似于节点的socket.on('message',…)

 import io.socket.client.Socket; import io.socket.client.IO; import io.socket.emitter.Emitter; final Socket socket; try{ socket = IO.socket("http://192.168.1.1:8080"); socket.on(Socket.EVENT_CONNECT, new Emitter.Listener() { @Override public void call(Object... args) { socket.emit("message", "hi"); socket.disconnect(); } }).on("message", new Emitter.Listener() { //message is the keyword for communication exchanges @Override public void call(Object... args) { socket.emit("message", "hi"); } }).on(Socket.EVENT_DISCONNECT, new Emitter.Listener() { @Override public void call(Object... args) {} }); socket.connect(); } catch(Exception e){ } 

Node.js端

使用socket.io创build正常的套接字