php從零搭建即時通訊(一.gatewayWork安裝及使用)
目錄
零.在thinkphp5環境下搭建gatewayWork環境
零.在thinkphp5環境下搭建gatewayWork環境
1.在官網上下載檔案包,傳送門https://www.workerman.net/download,根據自己機器的環境下載對應的gatewayWork即可
2.下載完成後解壓到你TP5專案的vendor目錄下即可,如圖
3.點選start_for_win.bat檔案即可成功啟動你的webSocked伺服器,如果你是linux的系統執行一下start.php檔案即可
dos介面如下即成功執行
一.在檢視檔案建立與webSocked伺服器的連線
因為是我的webSocked伺服器放在本地,所以地址就是127.0.0.1,到時候如果有需要,將地址改為你webSocked伺服器的地址就行
//連線websocket伺服器
let ws = new WebSocket("ws://127.0.0.1:8282");
坑:
有的瀏覽器可能預設沒有開啟webSocked,如果按照上面的程式碼你不能連線成功的話,可以根據的瀏覽器去設定一下即可
二.websocked伺服器向客戶端傳送訊息
注意伺服器所有的程式碼都在event檔案內編寫,並且改變該檔案內容和需要重啟webSocked伺服器
該檔案實體地址
D:\phpStudy2018\PHPTutorial\WWW\Qbling_mall\vendor\GatewayWorker\Applications\YourApp
在websocked伺服器上有三種傳送的方式
1.伺服器向所有客戶端傳送
Gateway::sendToAll($client_obj);
使用這行程式碼,伺服器就會向所有的與伺服器長連線的客戶端傳送訊息,其中$client_obj型別為字串由我們自定義,
我為了前後端互動方便,就將需要傳送的訊息的內容轉化為json物件
2.伺服器向某一客戶端傳送
//當客戶端連線的時候,要求客戶傳送uid進行繫結
Gateway::sendToClient($client_id,json_encode([
'type'=>'init',
'client_id' => $client_id
]));
使用這個方法,以後伺服器會向某個client_id傳送訊息,第一個引數為我們指定的client_id,第二個就是我們想要傳送的字串資訊
在這裡我們談談,client_id與uid,這兩個就像資料庫裡的主鍵一樣,
一個uid對應多個clientid,一個client_id只能對應一個uid
舉個例子,clientid就像你上學時的學號一樣,uid就像你的身份證號
你小學,中學,和大學的學號肯定不一樣吧,但是他們都對應你這個人
當我們使用長連線時,頁面的每一次重新整理,都會與伺服器都會重新給我們這個連結的客戶端生成一個新的clientid
就相當於你通過了高考,從高中到了大學,那麼你會重新獲得一個大學的學號,你的高中學號也就失去了意義,
但是,如果伺服器就想專門給你傳送一個訊息,怎麼辦呢,如果伺服器是給你的client_id傳送訊息,是很危險的
因為你這個客戶端可能中間重新整理了幾次,你的clientid就會像你的學號一樣發生了變化,所以可能會收不到資訊
這時候uid就出場了,它相當於你的身份證號,
伺服器直接給你的身份證號傳送訊息,它不管你現在處於什麼階段,clientid會不會改變,但是它知道你的uid是肯定不會變得,
所以伺服器就確保了這個資訊客戶端一定能收到(客戶端線上時)
3.伺服器向某一uid傳送(可能對應某幾個客戶端)
上面寫了對某一client_id傳送,那麼就肯定有對某一uid傳送啦,這裡引數基本與上面一致,就是clientid換成了uid
Gateway::sendToUid($client_obj->from_uid,json_encode([
"type"=>"server_msg",
"data"=>'繫結成功!'
]));
三.伺服器接受客戶端傳送的訊息
先簡單介紹下,伺服器端的三個回撥函式
1.onConnect
/**
* 當客戶端連線時觸發
* 如果業務不需此回撥可以刪除onConnect
*
* @param int $client_id 連線id
*/
public static function onConnect($client_id)
{
//code....
}
2.onMessage
/**
* 當客戶端發來訊息時觸發
* @param int $client_id 連線id
* @param mixed $message 具體訊息
*/
public static function onMessage($client_id, $message){
//code..
}
3.onClose
/**
* 當用戶斷開連線時觸發
* @param int $client_id 連線id
*/
public static function onClose($client_id)
{
//code...
}
就這麼簡單的三個函式,
一個客戶端連結上伺服器的時候會觸發,onConnect函式,然後一直連著,
什麼時候覺得無聊了,給伺服器發個訊息,這時候就會觸發onMesssage函式
,當客戶端覺得沒意識,決定下線時,會觸發onClose
其中我們基本上絕大多數的業務處理都放在onMessage函式內,在這個函式內我們接受客戶端給我們傳送的資訊
舉個栗子
/**
* 當客戶端發來訊息時觸發
* @param int $client_id 連線id
* @param mixed $message 具體訊息
*/
public static function onMessage($client_id, $message)
{
//獲取客戶端傳送的json
$client_obj = json_decode($message);
//判斷使用者傳送的資訊的型別
switch ($client_obj->type){
//將client與客戶端的uid繫結
case "bind":
Gateway::bindUid($client_id,$client_obj->from_uid);
Gateway::sendToUid($client_obj->from_uid,json_encode([
"type"=>"server_msg",
"data"=>'繫結成功!'
]));
break;
//code.............
//判斷某個使用者是否線上
case "is_online":
$status = Gateway::isUidOnline($client_obj->to_uid);
$data = [
"type" => "is_online",
"status" => $status,
];
//向傳送者返回接受者是否線上的訊息
Gateway::sendToUid($client_obj->from_uid,json_encode($data));
break;
}
}
根據我們與事先定義好的內容,來進行對應的邏輯操作
四.客戶端向websocked伺服器傳送訊息
在客戶端給伺服器傳送訊息就簡單了
ws.send(JSON.stringify(send_obj));
先根據我們定義的與伺服器連結的物件中的send方法就完事了,
但是注意傳送的訊息也只能是字串哦,
所以我為了方便資料的互動,將伺服器與客戶端所有互動的資料全部轉成了json格式
五.客戶端接受websocked伺服器傳送的訊息
這個也很簡單
ws.onmessage = function(e){
//code...
}
伺服器給客戶端傳送訊息時,會觸發們定義的與伺服器連結的物件中的onmessage方法
在這個方法裡面我們去寫相應的邏輯就歐克了