1.安装Workerman
composer require topthink/think-worker
2.配置Workerman
2.1 宝塔的网站 -> 配置文件
添加下列代码到上面图片中 端口这里开放的是:2345(具体看业务需求)
location /wss
{
proxy_pass http://127.0.0.1:2345;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header X-Real-IP $remote_addr;
}
2.2在项目跟目录下的 根目录/config/worker_server.php文件里面修改(没有自行创建),中
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2018 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
// +----------------------------------------------------------------------
// | Workerman设置 仅对 php think worker:server 指令有效
// +----------------------------------------------------------------------
return [
// 扩展自身需要的配置
'protocol' => 'websocket', // 协议 支持 tcp udp unix http websocket text
'host' => '0.0.0.0', // 监听地址
'port' => 2345, // 监听端口
'socket' => '', // 完整监听地址
'context' => [], // socket 上下文选项
'worker_class' => 'app\http\Worker', // 自定义Workerman服务类名 支持数组定义多个服务
// 支持workerman的所有配置参数
'name' => 'thinkphp',
'count' => 4,
'daemonize' => false,
'pidFile' => '',
// 支持事件回调
// onWorkerStart
'onWorkerStart' => function ($worker) {
},
// onWorkerReload
'onWorkerReload' => function ($worker) {
},
// onConnect
'onConnect' => function ($connection) {
},
// onMessage
'onMessage' => function ($connection, $data) {
$connection->send();
},
// onClose
'onClose' => function ($connection) {
},
// onError
'onError' => function ($connection, $code, $msg) {
echo "error [ $code ] $msg\n";
},
];
修改里面的
worker_class => "自定义目录地址" // 自定义Workerman服务类名 支持数组定义多个服务
2.3创建上面修改的自定义目录文件地址按上面修改的来我这里是在 跟目录下的app\http\下创建 Worker.php
<?php
namespace app\http;
use think\worker\Server;
use Workerman\Lib\Timer;
class Worker extends Server
{
protected $socket = 'websocket://0.0.0.0:2345';
protected static $heartbeat_time = 30; // 超时时间
public function onWorkerStart($worker)
{
Timer::add(10, function () use ($worker) {
$time_now = time();
foreach ($worker->connections as $connection) {
if (empty($connection->lastMessageTime)) {
$connection->lastMessageTime = $time_now;
continue;
}
if ($time_now - $connection->lastMessageTime > self::$heartbeat_time) {
$connection->close();
}
}
});
$inner_text_worker = new \Workerman\Worker('Text://0.0.0.0:9527');
$inner_text_worker->onMessage = function ($connection, $buffer) {
$buffer = json_decode($buffer, false);
$res = $this->send_all($buffer->message, $buffer->sid);
$connection->send($res ? 'ok' : 'fail');
};
$inner_text_worker->listen();
}
// 给指定的uid或者所有uid推送数据
public function send_all($message, $uid = '')
{
foreach ($this->worker->uidConnections as $conn) {
if (!empty($uid) && $conn->uid == $uid) {
$conn->send($message);
}
}
return true;
}
// 当有客户端连接时
public function onMessage($connection, $data)
{
$connection->lastMessageTime = time();
$arr = json_decode($data);
if ($arr->type == "bind") {
// 用户的uid是否存在不存在则赋值
if (!isset($connection->uid)) {
$connection->uid = $arr->uid;
$this->worker->uidConnections[$connection->uid] = $connection;
$connection->send(json_encode(array('type' => 'notice','msg' => '绑定身份')));
// 获取用户的离线消息
return;
}else{
$connection->send(json_encode(array('type' => 'notice','msg' => '已经绑定身份')));
return;
}
}
if ($arr->type == "text" && $arr->mode == "single") {
if (isset($this->worker->uidConnections[$arr->sid])) {
$connection = $this->worker->uidConnections[$arr->sid];
$connection->send($data);
echo 'user:' . $arr->sid . ' yes' . "\n";
} else {
echo 'user:' . $arr->sid . ' on' . "\n";
}
}
}
}