准备工作:
1 阿里云服务器:安全组 开放websocket 端口 比如:9999
2 宝塔:安全组 开放websocket 端口 9999
3 安装php8.1(你可以试试更高版本,我安装高版本总报错)
4.安装扩展 swoole6 redis
5.安装 thinkphp8
正式开始
1.在你thinkphp8 的根目录 运行命令
composer require topthink/think-swoole
2.生成默认的 Swoole 配置文件 config/swoole.php
:
php think swoole:publish
3.编辑生成的 config/swoole.php
文件,根据你的服务器环境和需求调整配置:
<?php
return [
'http' => [
'enable' => true,
'host' => '0.0.0.0',
'port' => 9501,
'worker_num' => swoole_cpu_num(),
'options' => ['daemonize' => true], // 守护进程运行,
],
'websocket' => [
'enable' => true,
'route' => true,
'handler' => \think\swoole\websocket\Handler::class,
'ping_interval' => 25000,
'ping_timeout' => 60000,
'room' => [
'type' => 'table',
'table' => [
'room_rows' => 8192,
'room_size' => 2048,
'client_rows' => 4096,
'client_size' => 2048,
],
'redis' => [
'host' => '127.0.0.1',
'port' => 6379,
'max_active' => 3,
'max_wait_time' => 5,
],
],
'listen' => [],
'subscribe' => [],
],
'rpc' => [
'server' => [
'enable' => false,
'host' => '0.0.0.0',
'port' => 9000,
'worker_num' => swoole_cpu_num(),
'services' => [],
],
'client' => [],
],
//队列
'queue' => [
'enable' => false,
'workers' => [],
],
'hot_update' => [
'enable' => env('APP_DEBUG', false),
'name' => ['*.php'],
'include' => [app_path()],
'exclude' => [],
],
//连接池
'pool' => [
'db' => [
'enable' => true,
'max_active' => 3,
'max_wait_time' => 5,
],
'cache' => [
'enable' => true,
'max_active' => 3,
'max_wait_time' => 5,
],
//自定义连接池
],
'ipc' => [
'type' => 'unix_socket',
'redis' => [
'host' => '127.0.0.1',
'port' => 6379,
'max_active' => 3,
'max_wait_time' => 5,
],
],
//锁
'lock' => [
'enable' => false,
'type' => 'table',
'redis' => [
'host' => '127.0.0.1',
'port' => 6379,
'max_active' => 3,
'max_wait_time' => 5,
],
],
'tables' => [],
//每个worker里需要预加载以共用的实例
'concretes' => [],
//重置器
'resetters' => [],
//每次请求前需要清空的实例
'instances' => [],
//每次请求前需要重新执行的服务
'services' => [],
];
关键配置说明:
worker_num:根据 CPU 核心数和业务负载调整,不宜过大。
enable_static_handler + document_root:让 Swoole 直接处理静态文件 (JS/CSS/图片),绕过 PHP 提升效率。
task_worker_num:启用异步任务处理 (如邮件发送、队列消费)。
max_request:预防 PHP 内存泄漏,Worker 处理一定请求后自动重启。
daemonize:生产环境设为 true,让服务在后台运行。
4.给你的项目配置一个域名
5.配置反向代理
代码如下:
location /ws {
proxy_pass http://127.0.0.1:9999; #端口改成自己的 指向 Swoole 端口
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 3600s;
}
6.写启动文件,我放在 控制器了
仅是示例,具体代码自己写
<?php
namespace app\controller;
use think\facade\Http;
use think\facade\Cache;
use Swoole\WebSocket\Server;
class WebSocket
{
public function start()
{
$server = new Server("0.0.0.0", 9999);
// 连接建立
$server->on('open', function ($server, $request) {
echo "客户端 {$request->fd} 连接\n";
});
// 消息处理
$server->on('message', function ($server, $frame) {
//可以写你的业务逻辑,然后进行 发送给当前这个连接的客户端
$server->push($frame->fd, json_encode($data));//推送给 当前连接
})
// 连接关闭
$server->on('close', function ($server, $fd) {
echo "客户端 {$fd} 断开\n";
});
$server->start();
}
}
?>
好了,在控制器中 直接运行 php WebSocket.php 就可以了
给一段前端测试代码
<html>
<head>
<title>websocket</title>
</head>
<body>
<h1>websocket功能</h1>
<input id="msg" type="text"/>
<button onclick="send()">发送</button>
<script>
var ws = new WebSocket("ws://你自己的域名/ws");
ws.onopen = function (){
console.log("连接成功");
}
ws.onclose = function (e) {
console.log("连接关闭", e.code, e.reason);
clearInterval(pingInterval);
setTimeout(() => location.reload(), 3000); // 3秒后重连^^1^^3^^
}
ws.onerror = function (e) {
console.error("连接错误", e);
}
ws.onmessage = function (evt) {
const textData = evt.data; // 直接获取文本内容
const jsonData = JSON.parse(textData);
console.log("JSON 对象:", jsonData);
}
function send(){
const msg = document.getElementById('msg').value;
ws.send("你好啊!"}));
}
</script>
</body>
</html>
那总不能一直用 命令 php 启动吧
我看了很多教程 他们没用原生的 代码,
他们的启动命令是 php think swoole
我可以启动,但是我连接失败
所以我用的是原生的代码(也就是我自己创建的 控制器的那个文件)
我自己创建的代码 我用命令 php think websocket:start 启动
配置方法如下:config/console.php 配置下面的代码,如果没有就自己建一个console.php
return [
'commands' => [
'websocket:start' => 'app\command\WebSocketCommand' //websocket 启动命令
]
];
其中 app\command\WebSocketCommand
对应 控制器中的 WebSocketCommand 文件
代码如下:
<?php
namespace app\command;
use think\console\Command;
use think\console\Input;
use think\console\Output;
use app\controller\WebSocket;
class WebSocketCommand extends Command
{
protected function configure()
{
$this->setName('websocket:start')
->setDescription('启动WebSocket服务');
}
protected function execute(Input $input, Output $output)
{
$output->writeln('WebSocket服务启动中...');
(new WebSocket())->start();
}
}
现在在项目根目录运行 php think websocket:start 就可以启动了
这个只适合调试,总不能这个黑窗口一直不关吧
在宝塔中安装 进程管理器
点启动就可以了,这样就可以不用开终端了