WebSocket是HTML5的一种新通信协议,它实现了浏览器与服务器之间的双向通讯。而Socket.IO是一个完全由JavaScript实现、基于Node.js、支持WebSocket的协议用于实时通信、跨平台的开源框架。
本文将根据 socket.io 官方提供的 socket.io-android-chat Demo 来讲解 socket.io 在android客户端实现即时通讯的一些基本操作。
附上github链接:
Demo实现了以下功能:
第一步,添加依赖到 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'
}
第二步,在 AndroidManifest.xml 中注册联网权限
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET" />
...
manifest>
现在我们可以在项目中使用socket.IO了~
我们可以通过 IO.socket(“URL”) 方法来获取一个 Socket 实例,其中 “URL” 为服务器地址。
Socket mSocket = IO.socket("http://chat.socket.io");
获取到 Socket 实例后,调用 connect() 方法即可与服务器建立连接。
mSocket.connect();
完整初始化代码如下:
import com.github.nkzawa.socketio.client.IO;
import com.github.nkzawa.socketio.client.Socket;
private Socket mSocket;
{
try {
//1.初始化socket.io,设置链接
mSocket = IO.socket("http://chat.socket.io");
} catch (URISyntaxException e) {}
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//2.建立socket.io服务器的连接
mSocket.connect();
}
我们可以通过 mSocket.emit(“KEY”, “VALUE”) 的方法来向服务器发送消息,”KEY”为事件的键, “VALUE”为事件的值,值支持任意类型的数据。
对服务器发送一个”new message”事件,其值为”hi~”:
mSocket.emit("new message", "hi~");
private EditText mInputMessageView;
//发送消息的方法
private void attemptSend() {
String message = mInputMessageView.getText().toString().trim();
if (TextUtils.isEmpty(message)) {
return;
}
mInputMessageView.setText("");
mSocket.emit("new message", message);
}
Socket.IO 是双向传递信息的 ,这意味着我们可以随时向服务器发送事件,也可以随时响应服务器返回来的事件。
我们可以通过 mSocket.on(“KEY”, LISTENER) 方法来监听服务器返回的事件。其中 “KEY” 为事件的键, LISTENER 为监听器,监听器的类型为 Emitter.Listener() 。
mSocket.on("new message", onNewMessage);
以下为一个监听 new message 事件的示例:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//使用 onNewMessage 来监听服务器发来的 "new message" 事件
mSocket.on("new message", onNewMessage);
mSocket.connect();
}
private Emitter.Listener onNewMessage = new Emitter.Listener() {
@Override
public void call(final Object.. args) {
//主线程调用
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
JSONObject data = (JSONObject) args[0];
String username;
String message;
try {
username = data.getString("username");
message = data.getString("message");
} catch (JSONException e) {
return;
}
// add the message to view
addMessage(username, message);
}
});
}
};
Emitter.Listener() 接口在 call 方法返回服务器传来的数据,需要注意的是,call方法是在子线程中执行的,如果我们需要在call方法中更新UI,则需使用 handler 或者 runOnUiThread 将操作放到主线程中来执行。
为避免内存泄漏等问题。 我们在socket使用完毕的时候,需要断开socket与服务器的连接,并且释放socket的监听事件。
断开服务器连接(disconnect):
mSocket.disconnect();
调用 off 方法释放监听事件:
mSocket.off("new message", onNewMessage);
在Activity结束时,释放socket:
@Override
public void onDestroy() {
super.onDestroy();
mSocket.disconnect();
mSocket.off("new message", onNewMessage);
}