swoole服务器运行过程中php文件是常驻内存运行,这样就可以避免重复的读取磁盘,重复的解释编译php,以便达到最高的性能,所以修改代码需要重启服务。
官网文档thinkphp6文档 https://www.kancloud.cn/manual/thinkphp6_0/1037479 swoole文档 https://wiki.swoole.com/#/ think-swoole文档 https://www.kancloud.cn/manual/thinkphp6_0/1359700 安装composer require topthink/think-swoole 命令行php think swoole [start|stop|reload|restart] 服务启动当你在命令行 'server' => [
'host' => env('SWOOLE_HOST', '0.0.0.0'), // 监听地址
'port' => env('SWOOLE_PORT', 9501), // 监听端口
'mode' => SWOOLE_PROCESS, // 运行模式 默认为SWOOLE_PROCESS
'sock_type' => SWOOLE_SOCK_TCP, // sock type 默认为SWOOLE_SOCK_TCP
'options' => [
// 服务启动后,进程ID存放文件
'pid_file' => runtime_path() . 'swoole.pid',
// swoole 的日志文件
'log_file' => runtime_path() . 'swoole.log',
// 守护进程模式设置 true 后台运行
'daemonize' => false,
// 设置启动的reactor线程数
'reactor_num' => swoole_cpu_num(),
// 设置启动的worker进程数
'worker_num' => swoole_cpu_num(),
//配置Task进程的数量
'task_worker_num' => swoole_cpu_num(),
//开启静态文件请求处理,需配合document_root
'enable_static_handler' => true,
//静态文件根目录
'document_root' => root_path('public'),
// 设置最大数据包尺寸,单位字节
'package_max_length' => 20 * 1024 * 1024,
//配置发送输出缓冲区内存尺寸
'buffer_output_size' => 10 * 1024 * 1024,
//设置客户端连接最大允许占用的内存数量
'socket_buffer_size' => 128 * 1024 * 1024,
],
],热更新swoole服务器运行过程中php文件是常驻内存运行,这样就可以避免重复的读取磁盘,重复的解释编译php,以便达到最高的性能,所以修改代码需要重启服务 think-swoole扩展提供热更新功能,在检测相关文件有更新会自动重启,不在需要手动完成重启,方便开发调试 生产环境下不建议开始文件监控,性能损耗,正常情况下你所修改的文件需要确认无误才能进行更新部署
'hot_update' => [
'enable' => env('APP_DEBUG', false),
'name' => ['*.php'],
'include' => [app_path()],
'exclude' => [],
],参数说明
websocket先来一个官方的例子 $server = new Swoole\WebSocket\Server("0.0.0.0", 9501);
$server->on('open', function (Swoole\WebSocket\Server $server, $request) {
echo "server: handshake success with fd{$request->fd}\n";
});
$server->on('message', function (Swoole\WebSocket\Server $server, $frame) {
echo "receive from {$frame->fd}:{$frame->data}\n";
$server->push($frame->fd, "this is server");
});
$server->on('close', function ($ser, $fd) {
echo "client {$fd} closed\n";
});
$server->start();开启think-swoole的websocket功能 'websocket' => [
'enable' => true,
],创建三个事件 php think make:listener SwWsConnect php think make:listener SwWsClose php think make:listener SwWsMessage 然后将这三个事件写到到事件监听中,分别有以下2中文件可以修改方式,注意二选一 thinkphp6自带的事件绑定 'listen' => [
........
// 监听链接
'swoole.websocket.Connect' => [
\app\listener\SwWsConnect::class
],
//关闭连接
'swoole.websocket.Close' => [
\app\listener\SwWsClose::class
],
//发送消息场景
'swoole.websocket.Message' => [
\app\listener\SwWsMessage::class
]
],think-swoole事件绑定 'listen' => [
'connect'=>\app\listener\SwWsConnect::class,
'close'=>\app\listener\SwWsClose::class,
'message'=> \app\listener\SwWsMessage::class
],怎么选择是保存在 开始写事件中中方法 连接事件 public function handle($event, \think\swoole\websocket $ws)
{
// 获取当前发送者的fd
$fd = $ws->getSender();
echo "server: handshake success with fd{$fd}\n";
}关闭事件 public function handle($event, \think\swoole\websocket $ws)
{
$fd = $ws->getSender();
echo "client {$fd} closed\n";
}message事件 public function handle($event, \think\swoole\websocket $ws)
{
$fd = $ws->getSender();
$data = json_encode($event);
echo "receive from {$fd}:{$data}\n";
$ws->emit("this is server", $fd);
}启动 think-swoole中的websocket方法总结 //给自己发消息
$ws->emit("this is server", $ws->getSender());
//给指定一个fd发消息
$ws->to($to)->emit("messagecallback",$data);
//给指定多个人发消息
$ws->to([1,2,3])->emit("messagecallback",$data);
//发送给所有的(不包含自己)
$ws->broadcast()->emit("messagecallback",$data);
//模拟formfd 给tofd 发送消息
$ws->setSender($formfd)->to($tofd)->emit("messagecallback",$data);注意:在多个实时通讯场景下使用 如果你发现你think-swoole中有些没有swoole中的方法可以这么干 $sw = app('swoole.server');
$sw = app("think\swoole\Manager")->getServer();
//以上二选一
$es = $sw->isEstablished($fd); //检查连接是否为有效的WebSocket客户端连接
var_dump($es);聊天室room实现前端文件参考 php think make:listener SwRoomJoin php think make:listener SwRoomLeave php think make:listener SwRoomMessage 事件绑定 // 加入房间
'swoole.websocket.RoomJoin' => [
\app\listener\SwRoomJoin::class
],
// 离开房间
'swoole.websocket.Roomleave' => [
\app\listener\SwRoomLeave::class
],
// 在房间发消息
'swoole.websocket.RoomMessage' => [
\app\listener\SwRoomMessage::class
]加入房间逻辑 public function handle($event, \think\swoole\websocket $ws, \think\swoole\websocket\room $room)
{
$fd = $ws->getSender();
//客户端假如定的room
$roomid = $event['room'];
//获取指定房间下有哪些客户端
$roomfds = $room->getClients($roomid);
// 判断这个房间有没有自己 如果有自己就不需要再次发送通知
if (in_array($fd, $roomfds)) {
$ws->to($roomfds)->emit("roomjoincallback", "房间{$roomid}已加入");
return;
}
//加入房间
$ws->join($roomid);
$ws->to($roomfds)->emit("roomjoincallback", "{$fd}加入房间{$roomid}成功");
}离开房间逻辑 public function handle($event, \think\swoole\websocket $ws, \think\swoole\websocket\Room $room)
{
$roomid = $event['room'];
$fd = $ws->getSender();
$roomfds = $room->getClients($roomid);
if (!in_array($fd, $roomfds)) {
$ws->emit("roomleavecallback", "{$fd}不在{$roomid}房间内,怎么离开~");
return;
}
//离开房间
$ws->leave($roomid);
//获取当前客户端加入了哪些客户端
$rooms = $room->getRooms($fd);
$ws->to($roomfds)->emit("roomleavecallback", "{$fd}已离开了~~");
}在房间发布聊天逻辑 public function handle($event, \think\swoole\websocket $ws, \think\swoole\websocket\room $room)
{
//
$roomid = $event['room'];
$text = $event['text'];
$fd = $ws->getSender();
$roomfds = $room->getClients($roomid);
if (!in_array($fd, $roomfds)) {
$ws->emit("roommessagecallback", "{$fd}不在{$roomid}房间内,无法进入发布聊天~");
return;
}
$ws->to($roomfds)->emit("roommessagecallback", $text);
}事件订阅php think make:listener SwSubscribe applistenerSwSubscribe.php <?php
declare (strict_types = 1);
namespace app\listener;
class SwSubscribe
{
protected $ws = null;
// public function __construct()
// {
// $this->ws = app('think\swoole\Websocket');
// }
public function __construct(\think\Container $c)
{
$this->ws = $c->make(\think\swoole\Websocket::class);
}
public function onConnect()
{
$fd = $this->ws->getSender();
echo "server: handshake success with fd{$fd}\n";
}
public function onClose()
{
$fd = $this->ws->getSender();
echo "client {$fd} closed\n";
}
public function onMessage($event)
{
$fd = $this->ws->getSender();
var_dump($event);
echo "server: handshake success with fd{$fd}\n";
$this->ws->emit("this is server", $fd);
}
}
Task任务投递https://wiki.swoole.com/#/start/start_task 生成事件 php think make:listener SwSendEmailTask 编写发送邮件方法 public function handle($event)
{
var_dump($event);
//
echo "开发发送邮件".time();
sleep(3);
echo "结束发送邮件".time();
}注册事件 'swoole.task'=>[
\app\listener\SwSendEmailTask::class
],在控制器中投递任务 public function doRegister()
{
$server = app('swoole.server');
$server->task(\app\listener\SwSendEmailTask::class);
return "注册成功";
}
public function doRegister(\think\swoole\Manager $manager)
{
$server = $manager->getServer();
$server->task(\app\listener\SwSendEmailTask::class);
return "注册成功";
}
public function doRegister(\Swoole\Server $server)
{
$server->task(\app\listener\SwSendEmailTask::class);
return "注册成功";
}三种获取在swoole中还有一个事件叫 定义一个发送邮件异步任务处理结果的事件 php think make:listener SwSendEmailFinish 注册事件 'swoole.finish'=>[
\app\listener\SwSendEmailFinish::class
],在task任务中调用 public function handle($event)
{
var_dump($event);
//
echo "开发发送邮件".time();
sleep(3);
echo "结束发送邮件".time();
$event->finish(\app\listener\SwSendEmailFinish::class);
}高性能共享内存 Tablehttps://wiki.swoole.com/#/mem... 先定结构在进行操作数据(原生swoole操作) $table = new Swoole\Table(1024);
//创建表
$table->column("id", Swoole\Table::TYPE_INT);
$table->column("name", Swoole\Table::TYPE_STRING);
$table->column("money", Swoole\Table::TYPE_FLOAT);
$table->create();
//添加数据
$table->set("zq", [
'id' => 1,
'name' => "zhiqiang",
'money' => 100,
]);
//获取一行数据
$table->get("zq");
// 修改数据
// 字段递增
$table->incr("zq","money",2);
//递减
$table->decr("zq","money",2);
// 返回 table 中存在的条目数。
$table->count();
//遍历table中的数据
foreach($table as $item){
var_dump($item);
}think-swoole中的操作 先对table表结构进行初始化 'tables' => [
'user'=>[
'size'=>1024,
'columns'=>[
[
'name'=>'id',
'type'=>\Swoole\Table::TYPE_INT
],
[
'name'=>'name',
'type'=>\Swoole\Table::TYPE_STRING,
'size'=>32
],
[
'name'=>'money',
'type'=>\Swoole\Table::TYPE_FLOAT
],
],
],
],操作数据 $table = app('swoole.table.user');
$table->set("zq", [
'id' => 1,
'name' => "zhiqiang",
'money' => 100
]);
//获取一行数据
$table->get("zq");
// 修改数据
// 字段递增
$table->incr("zq", "money", 2);
//递减
$table->decr("zq", "money", 2);
// 返回 table 中存在的条目数。
$table->count();
//遍历table中的数据
foreach ($table as $item) {
var_dump($item);
}
// 检查 table 中是否存在某一个 key。
$table->exist('zq');
//获取实际占用内存尺寸,单位字节
$table->momorySize();RPCRPC(Remote Procedure Call):远程过程调用,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的思想。 详细介绍:https://developer.51cto.com/a...
think-swoole实现RPC功能 服务器端接口定义 |
