# 與Laravel等框架結合
使用GatewayWorker時開發者最關心的是如何與現有mvc框架(ThinkPHP Yii laravel等)整合,以下是官方推薦的整合方式。見示意圖:

## 總體原則:
現有mvc框架項目與GatewayWorker獨立部署互不干擾
所有的業務邏輯都由網站頁面post/get到mvc框架中完成
GatewayWorker不接受客戶端發來的數據,即GatewayWorker不處理任何業務邏輯,GatewayWorker僅僅當做一個單向的推送通道
僅當mvc框架需要向瀏覽器主動推送數據時才在mvc框架中調用Gateway的API([GatewayClient](https://github.com/walkor/GatewayClient))完成推送
##具體實現步驟
1、網站頁面建立與GatewayWorker的websocket連接
2、GatewayWorker發現有頁面發起連接時,將對應連接的client_id發給網站頁面
3、網站頁面收到client_id后觸發一個ajax請求(假設是`bind.php`)將client_id發到mvc后端
4、mvc后端`bind.php`收到client_id后利用GatewayClient調用`Gateway::bindUid($client_id, $uid)`將client_id與當前uid(用戶id或者客戶端唯一標識)綁定。如果有群組、群發功能,也可以利用`Gateway::joinGroup($client_id, $group_id)`將client_id加入到對應分組
5、頁面發起的所有請求都直接post/get到mvc框架統一處理,包括發送消息
6、mvc框架處理業務過程中需要向某個uid或者某個群組發送數據時,直接調用[GatewayClient](https://github.com/walkor/GatewayClient)的接口`Gateway::sendToUid Gateway::sendToGroup`?等發送即可
## 示例代碼
GatewayWorker中Events.php代碼(只有個onConnect回調設置)
~~~
<?php
use \GatewayWorker\Lib\Gateway;
class Events
{
// 當有客戶端連接時,將client_id返回,讓mvc框架判斷當前uid并執行綁定
public static function onConnect($client_id)
{
Gateway::sendToClient($client_id, json_encode(array(
'type' => 'init',
'client_id' => $client_id
)));
}
// GatewayWorker建議不做任何業務邏輯,onMessage留空即可
public static function onMessage($client_id, $message)
{
}
}
~~~
網站頁面js片段
~~~
/**
* 與GatewayWorker建立websocket連接,域名和端口改為你實際的域名端口,
* 其中端口為Gateway端口,即start_gateway.php指定的端口。
* start_gateway.php 中需要指定websocket協議,像這樣
* $gateway = new Gateway(websocket://0.0.0.0:7272);
*/
ws = new WebSocket("ws://your_domain.com:7272");
// 服務端主動推送消息時會觸發這里的onmessage
ws.onmessage = function(e){
// json數據轉換成js對象
var data = eval("("+e.data+")");
var type = data.type || '';
switch(type){
// Events.php中返回的init類型的消息,將client_id發給后臺進行uid綁定
case 'init':
// 利用jquery發起ajax請求,將client_id發給后端進行uid綁定
$.post('./bind.php', {client_id: data.client_id}, function(data){}, 'json');
break;
// 當mvc框架調用GatewayClient發消息時直接alert出來
default :
alert(e.data);
}
};
~~~
mvc后端uid綁定代碼片段
bind.php (利用[GatewayClient](https://github.com/walkor/GatewayClient)綁定)
~~~
<?php
//加載GatewayClient。關于GatewayClient參見本頁面底部介紹
require_once '/your/path/GatewayClient/Gateway.php';
// GatewayClient 3.0.0版本開始要使用命名空間
use GatewayClient\Gateway;
// 設置GatewayWorker服務的Register服務ip和端口,請根據實際情況改成實際值(ip不能是0.0.0.0)
Gateway::$registerAddress = '127.0.0.1:1236';
// 假設用戶已經登錄,用戶uid和群組id在session中
$uid = $_SESSION['uid'];
$group_id = $_SESSION['group'];
// client_id與uid綁定
Gateway::bindUid($client_id, $uid);
// 加入某個群組(可調用多次加入多個群組)
Gateway::joinGroup($client_id, $group_id);
~~~
mvc后端發消息代碼片段
send_message.php (利用[GatewayClient](https://github.com/walkor/GatewayClient)發送)
~~~
<?php
//加載GatewayClient。關于GatewayClient參見本頁面底部介紹
require_once '/your/path/GatewayClient/Gateway.php';
// GatewayClient 3.0.0版本開始要使用命名空間
use GatewayClient\Gateway;
// 設置GatewayWorker服務的Register服務ip和端口,請根據實際情況改成實際值(ip不能是0.0.0.0)
Gateway::$registerAddress = '127.0.0.1:1236';
// 向任意uid的網站頁面發送數據
Gateway::sendToUid($uid, $message);
// 向任意群組的網站頁面發送數據
Gateway::sendToGroup($group, $message);
~~~
## 注意
以上僅是mvc框架與GatewayWorker官方推薦的結合方式,并不是強制使用此方式,開發者可以自由變化選擇結合方式以適應自己的業務需求。
當然也可以采用客戶端與GatewayWorker直接雙向通訊的方式完成業務通訊。
## 關于GatewayClient
源碼:
[https://github.com/walkor/GatewayClient](https://github.com/walkor/GatewayClient)
注意:
如果GatewayClient和GatewayWorker不是在同一臺服務器上,則需要先將start_gateway.php中的lanIp改成當前服務器的內網ip(如果不在一個內網可改成公網ip)。
如果GatewayClient和GatewayWorker在同一臺服務器上運行,則不用做任何更改,直接按照示例使用GatewayClient即可。
通過GatewayClient發送的數據不會經過Event.php,而是直接經由Gateway進程轉發給客戶端。
GatewayClient無法接收客戶端發來的數據。
客戶端使用示例
~~~
require_once '/your/path/GatewayClient/Gateway.php';
/**
* gatewayClient 3.0.0及以上版本加了命名空間
* 而3.0.0以下版本不需要use GatewayClient\Gateway;
**/
use GatewayClient\Gateway;
/**
*====這個步驟是必須的====
*這里填寫Register服務的ip(通常是運行GatewayWorker的服務器ip)和端口
*注意Register服務端口在start_register.php中可以找到(chat默認是1236)
*這里假設GatewayClient和Register服務都在一臺服務器上,ip填寫127.0.0.1
*注意:ip不能是0.0.0.0
**/
Gateway::$registerAddress = '127.0.0.1:1236';
// 以下是調用示例,接口與GatewayWorker環境的接口一致
// 接口具體使用方法見《Lib\Gateway類提供的接口》一章
// 注意除了不支持sendToCurrentClient和closeCurrentClient方法
// 其它方法都支持
Gateway::sendToAll($data);
Gateway::sendToClient($client_id, $data);
Gateway::closeClient($client_id);
Gateway::isOnline($client_id);
Gateway::bindUid($client_id, $uid);
Gateway::isUidOnline($uid);
Gateway::getClientIdByUid($uid);
Gateway::unbindUid($client_id, $uid);
Gateway::sendToUid($uid, $data);
Gateway::joinGroup($client_id, $group);
Gateway::sendToGroup($group, $data);
Gateway::leaveGroup($client_id, $group);
Gateway::getClientCountByGroup($group);
Gateway::getClientSessionsByGroup($group);
Gateway::getAllClientCount();
Gateway::getAllClientSessions();
Gateway::setSession($client_id, $session);
Gateway::updateSession($client_id, $session);
Gateway::getSession($client_id);
...
~~~
- 序言
- 開發必讀
- GeChat系統原理
- GeChat系統整體構建
- Laravel安裝配置
- GatewayWorker的結合
- Layim的結合
- PhpStorm配置碼云版本控制器
- 聊天系統功能的實現
- 用戶登錄
- 用戶注冊
- 用戶主頁
- 修改個性簽名
- 上傳頭像
- 修改用戶資料
- 在線狀態切換
- 查找功能
- 添加好友
- 查找/添加好友
- 消息盒子(一)
- 消息盒子(二)
- 添加群組
- 好友請求
- 創建群組
- 添加群組
- 管理群請求
- 獲取群成員
- 好友聊天
- 發送圖片
- 發送文件
- 用戶中心
- 用戶資料/修改密碼
- 退出
- 右鍵菜單
- 好友右鍵菜單
- 查看資料
- 歷史紀錄
- 刪除好友
- 屏蔽/接受消息
- 舉報好友
- 群組右鍵菜單
- 查看群資料
- 主面板右鍵菜單
- 好友分組右鍵菜單
- 數據表大全
- 全國各省市區代碼數據庫表
- 項目源碼