就在幾天前,本人突然發覺自己能力有待提高,於是乎就花錢買了幾節課學習了一下workerman中的GatewayWorker框架。
現總結如下:
入門:首先查看了workerman的官網https://www.workerman.net/ 上面有workerman、GatewayWorker的手冊和下載地址,瞭解了一下workerman作爲websocket的簡單解釋,之後便下載了GatewayWorker使用tp5框架開始測試開發。
本人開發環境wamp,項目總目錄chat,配置好項目可以正常訪問以後,首先將下載解壓後的GatewayWorker文件放在chat/vendor目錄下,首先修改了GatewayWorker/Applications/YourApp目錄下的start_gateway.php文件,將
$gateway = new Gateway("tcp://0.0.0.0:8282");
修改爲
$gateway = new Gateway("websocket://0.0.0.0:8282");
修改完以後,本人是在windows下開發所以打開GatewayWorker目錄,點擊start_for_win.bat就可以啓動socket服務,服務啓動以後並可以通過socket通信啦。
其中GatewayWorker中主要用到的文件是GatewayWorker/Application/YourApp目錄下的Events.php文件,裏面包含三個主要處理的方法,可以看一下注釋,一個是連接方法onConnect,初始化客戶端時首先要經過的就是該方法,這裏可以做的功能有統計客戶端數量、將socket服務給客戶端自定義的client_id發送到客戶端,以便進行客戶端自定義id與我們自己的用戶id進行綁定 ,這個可以稍後再說。第二個就是接受客戶端發送的消息方法onMessage,客戶端發送的消息都到達onMessage方法,然後在發送給指定的用戶或客戶端,客戶端發送消息時可以進行類別區分,在onMessage方法中可以根據類型處理不同的邏輯。第三個斷開連接時觸發的方法onClose,學習中只是簡單的介紹了一下該方法,並未真正時候,之後可以根據自己的業務需求做調整。
以上就是GatewayWorker裏面我們主要操作的方法,切記:每次變更Event.php文件都要關閉socket服務重新啓動,而且建議大家Event.php中只做通信功能,其他的邏輯處理不要在該文件裏處理,還有一點,客戶端(本人使用的老師給的html頁面做客戶端),本人在學習的時候在Event.php中用到的方法有Gateway::sendToClient()發送到客戶端、Gateway::bindUid()客戶端id與用戶id綁定以及Gateway::isUidOnline()用戶是否在線、Gateway::sendToUid()發送給指定用戶等等。
接下來從客戶端正式開始使用socket服務發送信息和接收信息,首先在頁面引入jq文件,然後在<script>標籤內建立通信
var ws = new WebSocket("ws://127.0.0.1:8282");
其中127.0.0.1是本地,是你socket服務所在的服務器ip,同上面啓動的服務所在服務器ip相同,端口相同纔可以連接服務成功,之後接收消息使用
ws.onmessage = function(e){
console.log(e);
}
所有接收到客戶端的消息都在上面方法中處理。
發送消息的方法是
ws.send(data);
data是發送的數據,這裏需要注意一點,客戶端發送的消息、Event.php中onMessage方法接收以後又發出的消息、以及客戶端onmessage數據都要統一爲json格式,接收到的數據是json格式,發送數據也要是json格式,下面一步一步開始開發:
1、首先將socket服務默認給客戶端的id與真實用戶綁定
啓動頁面是首先經過Event.php的onConnect()方法,但目前只知道client_id,所以把client_id發送到客戶端
public static function onConnect($client_id) { global $num; // 向當前client_id發送數據 //Gateway::sendToClient($client_id, "Hello $client_id\r\n"); // 向所有人發送 //Gateway::sendToAll("$client_id login\r\n"); echo "connect".++$num.":".$client_id."\n"; //在此綁定uid 但是這裏沒有uid 因此發送一個消息 Gateway::sendToClient($client_id,json_encode([ "type"=> "init", "client_id" => $client_id ])); }
2、html聊天頁面(該頁面一般可以通過控制器獲取到當前接收用戶id即fromid和要發送給對方的用戶id即toid)
接收到啓動時上面發送過來的信息,將當前用戶發送到Event.php中
var from_id = {$from_id}; var to_id = {$to_id}; var ws = new WebSocket("ws://127.0.0.1:8282"); ws.onmessage = function (e) {
var message = eval("("+e.data+")"); switch (message.type){
case "init": var data = '{"type":"bind","from_id":"'+from_id+'"}';
ws.send(data);
return;
} console.log(message); }
3、Event.php中onMessage()方法接收客戶端發送的消息,並進行綁定
public static function onMessage($client_id, $message) { $data = json_decode($message,true); if(!$data){ return; } switch ($data['type']){ case "bind": Gateway::bindUid($client_id,$data['from_id']); return; } }以上三步就將socket服務與我們真實的用戶id進行綁定,一個真實用戶可以綁定多個客戶端id
好累,明天在更吧~