版本:composer=1.8.5、php=7.4.3nts、think-worker=1.0.*
1、安装composer 1.8.5
D:\phpstudy_pro\Extensions\composer1.8.5
2、配置全局composer
环境变量——>系统变量——>path
添加:
D:\phpstudy_pro\Extensions\composer1.8.5
3、安装php 7.4.3nts
D:\phpstudy_pro\Extensions\php\php7.4.3nts
4、配置全局php
环境变量——>系统变量——>path
添加:
D:\phpstudy_pro\Extensions\php\php7.4.3nts
5、拷贝D:\phpstudy_pro\Extensions\composer1.8.5包下
composer.bat、composer.phar
至D:\phpstudy_pro\Extensions\php\php7.4.3nts根目录
并修改composer.bat内容为:
@php "%~dp0composer.phar" %*
6、全局配置国内源
composer config -g repo.packagist composer https://packagist.phpcomposer.com
7、下载think-worker
composer require topthink/think-worker=1.0.*
8、如需在window下做服务端,还需下载workerman
composer require workerman/workerman-for-win
9、根目录新建server.php
内容如下:
#!/usr/bin/env php
<?php
define('APP_PATH', __DIR__ . '/application/');
define('BIND_MODULE','push/Worker');
// 加载框架引导文件
require __DIR__ . '/thinkphp/start.php';
10、新建Worker.php
php think make:controller push/Worker
将里面的内容替换如下所示:
<?php
namespace app\push\controller;
use think\Db;
use think\worker\Server;
use Workerman\Lib\Timer;
class Worker extends Server
{
protected $socket = 'websocket://0.0.0.0:2346';
protected $snConnections = [];
protected $heartbeat_time = '55';
/**
* 收到信息
* @param $connection
* @param $data
*/
public function onMessage($connection, $datas)
{
// file_put_contents("./Result.txt", var_export($datas, true) . PHP_EOL, FILE_APPEND);
$connection->lastMessageTime = time();
$data = json_decode($datas);
if (empty($data->sn)) {
$connection->close();
return;
}
$sn = $data->sn;
switch ($data->type) {
case 'login':
// 保存该用户的输送数据
// file_put_contents('./Result.txt', 'login' . PHP_EOL, FILE_APPEND);
$this->snConnections[$sn] = $connection;
// 设备更新状态为在线状态
Db::name("device")->where('sn', '=', $sn)->update(['status' => '1']);
// file_put_contents("./Result.txt", var_export(Db::name("device")->getLastSql(), true) . PHP_EOL, FILE_APPEND);
$connection->send('login');
break;
case 'send':
// file_put_contents('./Result.txt', 'send' . PHP_EOL, FILE_APPEND);
$connection->send('ping');
break;
}
}
/**
* 当连接建立时触发的回调函数
* @param $connection
*/
public function onConnect($connection)
{
// $connection->send('ping');
}
/**
* 当连接断开时触发的回调函数
* @param $connection
*/
public function onClose($connection)
{
// file_put_contents('./Result.txt', 'close' . PHP_EOL, FILE_APPEND);
if (isset($connection->sn)) {
// 连接断开时删除映射
unset($this->snConnections[$connection->sn]);
// 设备更新状态为离线状态
Db::name("device")->where('sn', '=', $connection->sn)->update(['status' => '2']);
$connection->send('close');
}
}
/**
* 当客户端的连接上发生错误时触发
* @param $connection
* @param $code
* @param $msg
*/
public function onError($connection, $code, $msg)
{
echo "error $code $msg\n";
}
/**
* 每个进程启动
* @param $worker
*/
public function onWorkerStart($worker)
{
Timer::add(10, function () use ($worker) {
$time_now = time();
foreach ($worker->connections as $connection) {
// 有可能该connection还没收到过消息,则lastMessageTime设置为当前时间
if (empty($connection->lastMessageTime)) {
$connection->lastMessageTime = $time_now;
continue;
}
// $diff_time = $time_now - $connection->lastMessageTime;
// $msg = '距离上次通话已经过去' . $diff_time . '秒';
// $connection->send($msg);
// 上次通讯时间间隔大于心跳间隔,则认为客户端已经下线,关闭连接
if ($time_now - $connection->lastMessageTime > $this->heartbeat_time) {
$connection->close();
}
}
});
}
}
11、执行命令,启动服务
php server.php start -d
12、Google Chrome浏览器
打开:
http://127.0.0.1/index/user/login.html
F12:
控制台
输入如下代码,回车:
ws = new WebSocket("ws://127.0.0.1:2346");
ws.onopen = function() {
alert("连接成功");
ws.send(
JSON.stringify({
type: 'send',
sn: '123456'
})
);
};
ws.onmessage = function(e) {
alert("收到服务端的消息:" + e.data);
};
13、在thinkphp5.0.X版本早期会遇到长时间开启workerman服务会报错,原因是因为长时间链接数据库,导致数据库断线。
修改数据库配置application/database.php文件,
添加
// 是否需要断线重连
'break_reconnect' => true,