首发于个人博客 https://www.axie.cc/article/51
参考文档:
http://www.workerman.net/gatewaydoc/
1.下载:
界面如下图:
根据自己的运行环境下载相应的版本:两者除了启动方式不一样,其它文件都一样
- windows版本启动方式:运行下载下来的GatewayWorker-for-win\start_for_win.bat批处理文件
- Linux版本启动方式:运行GatewayWorker\start.php文件, // 全局启动脚本,此脚本会依次加载Applications/项目/start_*.php启动脚本
2.目录结构:
├── Applications // 这里是所有开发者应用项目
│ └── YourApp // 其中一个项目目录,目录名可以自定义
│ ├── Events.php // 开发者只需要关注这个文件
│ ├── start_gateway.php // gateway进程启动脚本,包括端口号等设置
│ ├── start_businessworker.php // businessWorker进程启动脚本
│ └── start_register.php // 注册服务启动脚本
│
├── start.php // 全局启动脚本,此脚本会依次加载Applications/项目/start_*.php启动脚本
│
└── vendor // GatewayWorker框架和Workerman框架源码目录,此目录开发者不用关心
提示:
1.客户端的事件及数据全部由Gateway转发给BusinessWorker处理,BusinessWorker默认调用Events.php中的onConnect onMessage onClose处理业务逻辑。
本地连接,类似逻辑代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0 user-scalable=no">
<title>沟通中</title>
</head>
<body>
<script>
var fromid = 4798;//用户实际IDa
与GatewayWorker建立websocket连接,域名和端口改为你实际的域名端口
ws = new WebSocket("ws://127.0.0.1:7272");
// 服务端主动推送消息时会触发这里的onmessage
ws.onmessage = function(e){
console.log("onmessage_begin");
// json数据转换成js对象
var data = JSON.parse(e.data);
var type = data.type || '';
switch (type){
case 'ping':
ws.send('{"type":"pong"}');
console.log("onmessage_ping");
console.log(data.msg);
break;
// Events.php中返回的init类型的消息,实际运用时,可以将client_id发给后台进行uid绑定
case 'init':
console.log("onmessage_init");
console.log(data.msg);
break;
case 'close':
console.log("非法接入client");
console.log(data.msg);
break;
}
}
</script>
</body>
</html>
2.通过GatewayClient发送的数据不会经过Event.php,而是直接经由Gateway进程转发给客户端。GatewayClient无法接收客户端发来的数据。
示例代码:
Gateway::$registerAddress = '127.0.0.1:1238';
$message = [
'type' => 4002,
'clientId' => $clientId,
'publish_time' => date('Y-m-d h:i:s', time())
];
Gateway::bindUid($clientId,$uid);
//在这里发送的信息是不走Event.php文件的,直接广播出去了
Gateway::sendToClient($clientId,json_encode($message));
如果GatewayClient和GatewayWorker不是在同一台服务器上,则需要先将start_gateway.php中的lanIp改成当前服务器的内网ip(如果不在一个内网可改成公网ip)。
如果GatewayClient和GatewayWorker在同一台服务器上运行,则不用做任何更改,直接按照示例使用GatewayClient即可。
3.运行测试:
1.运行gateway.php
2.start_gateway.php文件,这个文件是默认的文件,默认协议是text协议:
// gateway 进程,这里使用Text协议,可以用telnet测试
$gateway = new Gateway("Text://0.0.0.0:8282");
//想用js连接情况下:
$gateway = new Gateway("ws://0.0.0.0:8282");
3.本地测试text协议是否正常命令,cmd运行:
telnet 127.0.0.1 8282
界面显示:
4.重新打开一个窗口:window测试结果:
5.Linux 测试结构:
6.测试成功!
开始实战:
我们只要对这四个文件进行了解:
├── Applications // 这里是所有开发者应用项目
│ └── YourApp // 其中一个项目目录,目录名可以自定义
│ ├── Events.php // 开发者只需要关注这个文件
│ ├── start_gateway.php // gateway进程启动脚本,包括端口号等设置
│ ├── start_businessworker.php // businessWorker进程启动脚本
│ └── start_register.php // 注册服务启动脚本
1.修改start_gateway.php文件的这句配置,换成自己喜欢的协议与接口
// gateway 进程,这里使用Text协议,可以用telnet测试
$gateway = new Gateway("Websocket://0.0.0.0:7272");
2.修改Events.php 响应数据
//部分代码
class Events
{
static $num = 0;
/**
* 当客户端连接时触发的事件。
* @param $client_id
*/
public static function onConnect($client_id)
{
global $num;
Gateway::sendToClient($client_id, json_encode(array(
'type' => 'init',
'msg' => $client_id
)));
}
/**
* 有消息时
* @param int $client_id
* @param mixed $message
*/
public static function onMessage($client_id, $message)
{
// 客户端传递的是json数据
$message_data = json_decode($message, true);
if(!$message_data)
{
return ;
}
switch($message_data['type']){
case "bind":
$fromid = $message_data['fromid'];
Gateway::bindUid($client_id, $fromid);
Gateway::sendToUid($message_data['fromid'],json_encode(['type'=>'bind','msg'=>'绑定成功'])); //返回给发送者
return;
}
//其它case 情况
}
/**
* 当用户断开连接时触发
* @param int $client_id 连接id
*/
public static function onClose($client_id)
{
// 向所有人发送
GateWay::sendToAll("$client_id logout\r\n");
}
}
3. 在html中调用,观察console的数据
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0 user-scalable=no">
<title>沟通中</title>
</head>
<body>
<script>
var fromid = 4798;//用户实际IDa
与GatewayWorker建立websocket连接,域名和端口改为你实际的域名端口
ws = new WebSocket("ws://127.0.0.1:7272");
// 服务端主动推送消息时会触发这里的onmessage
ws.onmessage = function(e){
console.log("onmessage_begin");
// json数据转换成js对象
var data = JSON.parse(e.data);
var type = data.type || '';
switch (type){
case 'ping':
ws.send('{"type":"pong"}');
console.log("onmessage_ping");
console.log(data.msg);
break;
// Events.php中返回的init类型的消息,实际运用时,可以将client_id发给后台进行uid绑定
case 'init':
console.log("onmessage_init");
console.log(data.msg);
break;
case 'close':
console.log(data.msg);
break;
}
}
</script>
</body>
</html>
注意:注册端口
文件:Applications\YourApp\start_register.php Applications\YourApp\start_gateway.php Applications\YourApp\start_businessworker.php
中的注册地址要一样
//start_register.php
// 服务注册地址
$gateway->registerAddress = '127.0.0.1:1238';
//start_businessworker.php
// 服务注册地址
$worker->registerAddress = '127.0.0.1:1238';
//start_register.php
// register 必须是text协议
$register = new Register('text://0.0.0.0:1238');