在這篇文章你將學習到:
一、簡介
WebSocket是HTML5最新提出的規範,雖然主流瀏覽器都已經支持,但仍然可能有不兼容的情況,爲了兼容所有瀏覽器,給程序員提供一致的編程體驗,SocketIO將WebSocket、AJAX和其它的通信方式全部封裝成了統一的通信接口,也就是說,我們在使用SocketIO時,不用擔心兼容問題,底層會自動選用最佳的通信方式。因此說,WebSocket是SocketIO的一個子集。
而 socket.io 的學習也非常簡單,如果你使用過 nodejs ,並用 socket.io 搭建信令服務器,就會發現,Android 端的 API 與 js 的基本一致,在學習 Android 端的 socket.io ,官網也給出了例子:
Android 例子: https://github.com/nkzawa/socket.io-android-chat
本項目地址:https://github.com/LillteZheng/SocketIoDemo
項目效果如下:
二、socket 重要 api
首先關聯 socket.io
compile ('io.socket:socket.io-client:1.0.0') {
// excluding org.json which is provided by Android
exclude group: 'org.json', module: 'json'
}
在 Androidminafest.xml中加入網絡權限:
<uses-permission android:name="android.permission.INTERNET"/>
接着認識兩個比較主要的api ,sockt.emit 和 socket.on:
emit 和 on 是相互相成的,當 on 註冊中的關鍵字與 emit 匹配時,on 的事件纔會相應:
比如客戶端註冊了 login 事件:
mSocket.on("login",LoginListener);
此時,只有 服務器端那邊發送了 socket.emit(“login”)或者其他服務端也發送了,該事件纔會響應;
三、實現一個多人聊天
其實官網已經有例子了,我的demo只是在它的基礎上優化了一些結構:
首先是獲取 socket 的實例和開始連接:
public Socket getSocket(){
if (mSocket == null) {
try {
mSocket = IO.socket(IO_SERVER_URL);
} catch (URISyntaxException e) {
e.printStackTrace();
}
}
mSocket.connect();
return mSocket;
}
其中 IO_SERVER_URL 爲:
private static final String IO_SERVER_URL = "https://socket-io-chat.now.sh/";
它是socket.io官網提供,若自己編寫了scoekt.io的服務器,也可以直接替換 url
官網的 URL 有幾個回調屬性:
// 發送 add user 之後會回調 login
mSocket.emit("add user",name);
所以,我們可以在 login 的回調中,跳轉到其他頁面:
在 MsgFragment 找那個,主要註冊相關的事件即可:
private void getSocketMsg(){
mSocket.on("user joined", new Emitter.Listener() {
@Override
public void call(Object... args) {
JSONObject data = (JSONObject) args[0];
String username;
int numUsers;
try {
username = data.getString("username");
numUsers = data.getInt("numUsers");
} catch (JSONException e) {
Log.e(TAG, e.getMessage());
return;
}
updateUI(new User(username," 加入房間"));
}
});
mSocket.on("new message", new Emitter.Listener() {
@Override
public void call(Object... args) {
JSONObject data = (JSONObject) args[0];
String username;
int message;
try {
username = data.getString("username");
message = data.getInt("message");
} catch (JSONException e) {
Log.e(TAG, e.getMessage());
return;
}
updateUI(new User(username,": "+message));
}
});
mSocket.on("user left", new Emitter.Listener() {
@Override
public void call(Object... args) {
JSONObject data = (JSONObject) args[0];
String username;
try {
username = data.getString("username");
} catch (JSONException e) {
Log.e(TAG, e.getMessage());
return;
}
updateUI(new User(username," 離開了房間"));
}
});
}
其中發送新消息事件爲:
mSocket.emit("new message", message);
最後,別忘了在活動結束,關閉連接:
@Override
public void onDestroy() {
super.onDestroy();
mSocket.off();
mSocket.disconnect();
}