之前寫了一個安卓app吊档,其中使用了即時通信,簡單的用了websocket唾糯,這里簡單說明一下
- websocket是什么
http://www.ruanyifeng.com/blog/2017/05/websocket.html
簡單理解就是能在兩個端通信的一個協(xié)議籍铁,也可以用socket涡上。
兩邊都監(jiān)聽自己的一個端口趾断,端口收到數(shù)據(jù)就展示出來拒名,想要發(fā)送數(shù)據(jù)就發(fā)送到這個端口即可
注意,執(zhí)行流程是:服務端先啟動芋酌,然后客戶端向服務端發(fā)起連接增显,這樣就建立了1對連接,每個客戶端都向服務器發(fā)起連接脐帝,建立n對連接同云,每個客戶端都可以和服務端進行通信
- 兩個app如何通信
這里需要服務器做轉(zhuǎn)發(fā)了,A->SERVER->B
堵腹;B->SERVER->A
炸站;就是app把信息發(fā)給服務器,服務器再轉(zhuǎn)發(fā)給另一個app疚顷,那么服務器怎么知道誰是另一個呢旱易?我們可以做一個簡單的注冊和轉(zhuǎn)發(fā)。具體如下:
每個客戶端app都要連接websocket服務端腿堤,連接之后服務器端會保存這個客戶端的連接信息阀坏,可以從這個連接獲取信息或者發(fā)送信息給這個連接
現(xiàn)在服務端就有了所有已連接的app信息了,但是還是不知道誰是誰笆檀,所以要求app在連接的時候通報服務端用戶id 是 什么忌堂,在服務端把用戶id和連接信息關聯(lián)起來,然后根據(jù)用戶id找到連接信息去轉(zhuǎn)發(fā)酗洒。
在app發(fā)消息的時候士修,我們可以簡單規(guī)定一個格式,fromid:toid:msg
樱衷,當然也可以規(guī)定一個更復雜的協(xié)議棋嘲,服務端收到之后拿到toid去轉(zhuǎn)發(fā)。
// 服務端收到信息的操作
list($fromId,$toId,$msg) = explode(":",$data);
Log::info("receive-"."from=".$fromId."To=".$toId."msg=".$msg);
if (!array_key_exists($fromId,$worker->uidConnections) || $worker->uidConnections[$fromId] != $connection) {
$worker->uidConnections[$fromId] = $connection;
Log::info("this user first comes,his email=".$fromId);
}
// 安卓端點擊發(fā)送的操作箫老,拼接了我們說的格式
sendBtn.setOnClickListener(v -> {
String content=inputText.getText().toString();
if("".equals(content))
return;
if (client != null && client.isOpen()) {
Log.i("WebSocket",content);
client.send(myEmail+":"+toEmail+":"+content);
}
msgList.add(new Msg(content, Msg.TYPE.SENT));
//如果有新消息封字,則設置適配器的長度(通知適配器,有新的數(shù)據(jù)被插入)耍鬓,并讓 RecyclerView 定位到最后一行
int newSize = msgList.size() - 1;
adapter.notifyItemInserted(newSize);
msgRecyclerView.scrollToPosition(newSize);
//清空輸入框中的內(nèi)容
inputText.setText("");
});
- 用到的框架
安卓用的是implementation "org.java-websocket:Java-WebSocket:1.4.0"
這個工具
php用的是ThinkPHP
+WorkerMan
- 源代碼
近期代碼不能公開阔籽,需要交流的可以留言