一、安装 workerman
在项目根目录执行
composer require workerman/workerman二、创建自定义 artisan 命令来启动 workerman 服务
由于 laravel 不能直接在根目录下执行 php 命令,所以需要创建 artisan 命令用于后面 workerman 服务的开启。
1,生成 WorkermanCommand 文件
php artisan make:command WorkermanCommand执行以上命令行会在 app/Console/Commands/ 目录下生成 WorkermanCommand.php 文件。
<?php
namespace App\Console\Commands;
use Workerman\Worker;
use Illuminate\Console\Command;
class WorkermanCommand extends Command
{
private $server;
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'wk {action}';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Start a Workerman server.';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
global $argv;
$arg = $this->argument('action');
$argv[1] = $argv[2];
$argv[2] = isset($argv[3]) ? "-{$argv[3]}" : '';
switch ($arg) {
case 'start':
$this->start();
break;
case 'stop':
break;
case 'restart':
break;
case 'reload':
break;
case 'status':
break;
case 'connections':
break;
}
}
private function start()
{
// 创建一个Worker监听20002端口,不使用任何应用层协议
$this->server = new Worker("tcp://0.0.0.0:20002");
// 启动4个进程对外提供服务
$this->server->count = 4;
$handler = \App::make('handlers\WorkermanHandler');
// 连接时回调
$this->server->onConnect = [$handler, 'onConnect'];
// 收到客户端信息时回调
$this->server->onMessage = [$handler, 'onMessage'];
// 进程启动后的回调
$this->server->onWorkerStart = [$handler, 'onWorkerStart'];
// 断开时触发的回调
$this->server->onClose = [$handler, 'onClose'];
// 运行worker
Worker::runAll();
}
}我只实现了 start 命令,其他命令童鞋们自行实现吧。
这里使用了 PHP 类方法的回调。(PHP几种回调写法)
这里我们创建了一个自定义命令 wk [action] ,通过此命令即可开启 workerman 服务。
注册命令
https://laravel-china.org/docs/laravel/5.4/artisan/1245#7ed55e
命令编写完成后,需要注册 Artisan 后才能使用。注册文件为 app/Console/Kernel.php 。在这个文件中, 你会在 commands 属性中看到一个命令列表。要注册你的命令,只需将其加到该列表中即可。当 Artisan 启动时,所有罗列在这个 属性的命令,都会被 服务容器 解析并向 Artisan 注册:
protected $commands = [
//
Commands\WorkermanCommand::class
];在这个自定义命令还引用了其他的类文件,如:
$handler = \App::make('handlers\WorkermanHandler');所以,需要创建一个 WorkermanHandler.php 的文件来处理对应的操作。
2,创建 WorkermanHandler.php
创建文件 app/handlers/WorkermanHandler.php
<?php
namespace handlers;
use Workerman\Lib\Timer;
// 心跳间隔10秒
define('HEARTBEAT_TIME', 10);
class WorkermanHandler
{
// 处理客户端连接
public function onConnect($connection)
{
echo "new connection from ip " . $connection->getRemoteIp() . "\n";
}
// 处理客户端消息
public function onMessage($connection, $data)
{
// 向客户端发送hello $data
$connection->send('Hello, your send message is: ' . $data);
}
// 处理客户端断开
public function onClose($connection)
{
echo "connection closed from ip {$connection->getRemoteIp()}\n";
}
public function onWorkerStart($worker)
{
Timer::add(1, function () use ($worker) {
$time_now = time();
foreach ($worker->connections as $connection) {
// 有可能该connection还没收到过消息,则lastMessageTime设置为当前时间
if (empty($connection->lastMessageTime)) {
$connection->lastMessageTime = $time_now;
continue;
}
// 上次通讯时间间隔大于心跳间隔,则认为客户端已经下线,关闭连接
if ($time_now - $connection->lastMessageTime > HEARTBEAT_TIME) {
echo "Client ip {$connection->getRemoteIp()} timeout!!!\n";
$connection->close();
}
}
});
}
}3,修改 composer.json 文件,让 app/handlers 文件夹下的类文件自动加载。
"autoload": {
"classmap": [
...
"app/handlers"
],
...
},运行命令类文件自动加载:
composer dump-autoload至此。workman的命令定义已经完成。
使用:
php artisan wk start如果看到以下内容,说明 workerman 服务启动正常:
Workerman[artisan] start in DEBUG mode
----------------------- WORKERMAN -----------------------------
Workerman version:3.5.4 PHP version:7.1.4
------------------------ WORKERS -------------------------------
user worker listen processes status
root none tcp://0.0.0.0:20002 1 [OK]
----------------------------------------------------------------
Press Ctrl+C to quit. Start success.
简单的开发实例
实例一、使用HTTP协议对外提供Web服务
创建http_test.php文件(位置任意,能引用到Workerman/Autoloader.php即可,下同)
命令行运行(windows用户用 cmd命令行,下同)
测试
假设服务端ip为127.0.0.1
在浏览器中访问url http://127.0.0.1:2345
实例二、使用WebSocket协议对外提供服务
创建ws_test.php文件
命令行运行
测试
打开chrome浏览器,按F12打开调试控制台,在Console一栏输入(或者把下面代码放入到html页面用js运行)
实例三、直接使用TCP传输数据
创建tcp_test.php
命令行运行
测试:命令行运行 (以下是linux命令行效果,与windows下效果有所不同)
慎用composer update
Vue中使用websocket的正确使用方法
linux用nohup在后台常驻运行php脚本
小程序使用wss
微信小程序wss地址不允许使用端口,于是就利用nginx转发。
1、nginx版本是需要大于1.3
2、nginx配置文件修改
3、GatewayWorker下的修改,用了nginx就不需要在此处使用ssl了,文档有提到 https://www.kancloud.cn/walkor/workerman/315297
4、小程序那直接使用这个url : wss://域名/wss
杀杀杀
想干嘛?
PHP获取客户端的真实IP
使用bootstrap carousel时的"Cannot read property 'offsetWidth' of undefined"问题
Bootstrap Carousel: Uncaught TypeError: Cannot read property 'offsetWidth' of undefined
“列表左滑”对往上方滑屏过于敏感
cu-custom作为小程序头部在IOS下会被拉动;且偶尔会整体偏移向上,目测是因为padding的部分被偏移出屏幕导致的,且下拉不会回来。
在使用Laravel框架的时候,调试的时候,需要将查询的SQL输出校验,这是需要将SQL打印出来
Laravel 系列:orWhere 条件式
foreach()循环
要跳出本次循环继续执行下次循环 continue
终止循环
break。
客服消息
在页面使用客服消息
需要将 button 组件 open-type 的值设置为 contact,当用户点击后就会进入客服会话,如果用户在会话中点击了小程序消息,则会返回到小程序,开发者可以通过 bindcontact 事件回调获取到用户所点消息的页面路径 path 和对应的参数 query。
path 小程序消息指定的路径
query 小程序消息指定的查询参数
修改 return $_GET["echostr"]
return回来的echostr是带双引号,而echo回来的echostr是不带双引号的。
nginx 反向代理 wss转ws 服务端不变
Workerman kill
调试模式
php中访问对象中名字叫0的成员
laravel框架的whereIn条件或者where条件里面的in条件
可以用when方法去写