转载地址:https://www.cnblogs.com/shenqilun/articles/11322858.html
参考地址:
1.https://blog.csdn.net/qq_38882327/article/details/89352916
2.http://doc2.workerman.net/326107
3.https://blog.csdn.net/sinat_34469308/article/details/84799728 (这个也很有用 绑定的方法不一样)
4.http://www.ptbird.cn/gateway-worker-many-people-chat-online-group.html
5.https://blog.csdn.net/qq_38211838/article/details/82020708
一、下载
1、GatewayWorker
百度网盘
链接:https://pan.baidu.com/s/1L0cK6ol2Cx-h34ZzLGQ_Sg
提取码:bgrb
官方
https://www.workerman.net/download/GatewayWorker.zip
2、thinkphp3.2.3
链接:https://pan.baidu.com/s/1K7XPQbOdUibVvGOtDYm9LQ
提取码:3xg0
二、GatewayWorker thinkphp3.2 整合
1、复制GatewayWorker\vendor\workerman\gateway-worker\src到ThinkPHP\Library文件夹下,更名为GatewayWorker。除了DbConnection.php之外的所有文件全部改成.class.php结尾。
2、复制GatewayWorker\vendor\workerman\workerman到ThinkPHP\Library文件夹下,更名为Workerman。除了Constants.php之外的所有文件全部改成.class.php结尾。
2.1、将Worker.class.php文件的831行-836行改为
if (!isset($argv[2]) || !in_array($argv[2],
$available_commands)) {
exit($usage);
}
2.2、将Worker.class.php文件的831行-836行改为839行-840行改为
$command = trim($argv[2]);
$command2 = isset($argv[3]) ? $argv[3] : '';
image.png
三、源码
Application\Demo\Controller\IManController.class.php
<?php
namespace Demo\Controller;
use Think\Controller;
use GatewayWorker\Lib\Gateway;
class ManController extends Controller {
public function index(){
//$uid = I('uid'); //发信人ID,获取登录时ID
session('uid', '520');//先固定为520
$this->display();
}
/**
* client_id与uid绑定操作
*/
public function bind(){
$client_id = I('client_id');
$uid = session('uid');
//client_id与uid绑定操作
Gateway::bindUid($client_id, $uid);
$message = '绑定成功' . $uid . '-' . $client_id;
//推送成功消息
Gateway::sendToUid($uid, json_encode($message));
// 加入某个群组(可调用多次加入多个群组)
//Gateway::joinGroup($client_id, $group_id);
}
/**
* 发送信息
*/
public function sendmsg(){
$uid = session('uid');
$message = '222';
//向任意uid的网站页面发送数据
Gateway::sendToUid($uid, $message);
//向所有用户发送
//Gateway::sendToAll($message);
//向某个client_id对应的连接发消息
//Gateway::sendToClient($client_id, $data);
// 向任意群组的网站页面发送数据
//Gateway::sendToGroup($group, $message);
}
}
Application\Demo\SocketController.class.php
<?php
namespace Demo\Controller;
use Workerman\Worker;
use Workerman\Autoloader;
use GatewayWorker\Gateway;
use GatewayWorker\BusinessWorker;
use GatewayWorker\Register;
use Demo\Controller\EventsController as Events;
class SocketController{
//http://doc3.workerman.net/1146859
//Error: multi workers init in one php file are not support
public function __construct(){
}
public function start(){
// $this->startRegister();
// $this->startBusinessWorker();
// $this->startGateWay();
// Worker::runAll();
}
public function startRegister(){
// new Register('text://lhygtest.com:1237');//本地
new Register('text://lhygtest.com:1237');//正式
Worker::runAll();
}
public function startBusinessWorker(){
$worker = new BusinessWorker();
$worker->name = 'BusinessWorker';// worker名称
$worker->count = 1;// bussinessWorker进程数量
// $worker->registerAddress = '127.0.0.1:1237';// 本地服务注册地址
$worker->registerAddress = '127.0.0.1:1237';// 正式服务注册地址
$worker->eventHandler = Events::class;//设置处理业务的类,此处制定Events的命名空间
Worker::runAll();
}
public function startGateWay(){
// $gateway = new Gateway("Websocket://0.0.0.0:7272");// 本地 gateway 进程
$gateway = new Gateway("websocket://lhygtest.com:8282");// 正式 gateway 进程
$gateway->name = 'Gateway';// 设置名称,方便status时查看
$gateway->count = 4;// 设置进程数,gateway进程数建议与cpu核数相同
// $gateway->lanIp = '127.0.0.1';// 本地分布式部署时请设置成内网ip(非192.168.10.149)
$gateway->lanIp = '127.0.0.1';// 正式分布式部署时请设置成内网ip(非192.168.10.149)
$gateway->startPort = 2900;// 内部通讯起始端口,假如$gateway->count=4,起始端口为4000
$gateway->pingInterval = 100;// 心跳间隔
$gateway->pingData = '{"type":"ping"}';// 心跳数据
// $gateway->registerAddress = '127.0.0.1:1237';// 本地服务注册地址
$gateway->registerAddress = '127.0.0.1:1237';// 正式服务注册地址
Worker::runAll();
}
}
Application\Demo\Controller\EventsController.class.php
<?php
namespace Demo\Controller;
use Think\Controller;
/**
* 用于检测业务代码死循环或者长时间阻塞等问题
* 如果发现业务卡死,可以将下面declare打开(去掉//注释),并执行php start.php reload
* 然后观察一段时间workerman.log看是否有process_timeout异常
*/
//declare(ticks=1);
/**
* 聊天主逻辑
* 主要是处理 onConnect
*/
use GatewayWorker\Lib\Gateway;
class EventsController
{
// 当有客户端连接时,将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)
{
}
}
Application/Demo/View/Man/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>WebSocket示例</title>
<script type="text/javascript" src="http://cdn.bootcss.com/jquery/3.1.1/jquery.min.js"/></script>
</head>
<body>
<script type="text/javascript">
/**
* 与GatewayWorker建立websocket连接,域名和端口改为你实际的域名端口,
* 其中端口为Gateway端口,即start_gateway.php指定的端口。
* start_gateway.php 中需要指定websocket协议,像这样
* $gateway = new Gateway(websocket://0.0.0.0:7272);
*/
ws = new WebSocket("ws://"+document.domain+":8282");
// 服务端主动推送消息时会触发这里的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':
console.log(data);
// 利用jquery发起ajax请求,将client_id发给后端进行uid绑定
$.post("{:U('Man/bind')}",{client_id: data.client_id},function(data){},'json');
break;
case 'ping':
console.log(data);
//心跳检测 不执行操作
break;
// 当mvc框架调用GatewayClient发消息时直接alert出来
default ://服务器端发送过来的数据
alert(e.data);
}
};
</script>
</body>
</html>
四、运行
1、Liunx下进入网站根目录(与index.php入口文件同级目录),执行命令 php index.php Home/Socket/start start
- windows下 进入网站根目录(与index.php入口文件同级目录),执行命令
php index.php Home/Socket/startRegister start
php index.php Home/Socket/startBusinessWorker start
php index.php Home/Socket/startGateWay start
image.png
网友评论