- 后端
- 即时通讯
【免费下载链接】laravel-websockets
Websockets for Laravel. Done right.
在完成 WebSocket 应用(Apps)与 Pusher 相关配置之后,启动整个 Laravel WebSockets 服务器只需要一条 Artisan 命令。本篇指南将以 docs/basic-usage/starting.md 为核心骨架,深入讲解php artisan websockets:serve的默认行为、--port与--host两个核心选项的用法,并结合仓库源码剖析命令启动后的内部流程、生产环境下的常驻运行方案以及验证调试手段。读完本文,你将能够根据实际部署需求灵活选择端口、控制监听网卡,并理解这条命令在按下回车后究竟发生了什么。
启动前的前置条件
在运行启动命令之前,请确认以下两项配置已经完成:
- 安装并发布配置:通过
composer require beyondcode/laravel-websockets安装包,并执行php artisan vendor:publish --provider="BeyondCode\LaravelWebSockets\WebSocketsServiceProvider" --tag="config"发布 config/websockets.php 配置文件(详见 docs/getting-started/installation.md)。 - 配置 WebSocket Apps 与 Pusher 设置:默认情况下,服务器从配置文件中的
apps数组读取应用凭证(id、key、secret),这些值取自PUSHER_APP_*环境变量;同时需要将 Laravel 的广播驱动设为pusher,并在config/broadcasting.php中将host与port指向你自己的 WebSocket 服务器(详见 docs/basic-usage/pusher.md)。
完成上述配置后,即可启动服务器。
一条命令启动服务器
启动 Laravel WebSocket 服务器的核心命令非常简单:
php artisan websockets:serve该命令对应的实现位于 src/Console/Commands/StartServer.php。从命令签名(src/Console/Commands/StartServer.php#L26-L33)可以看到,它声明了全部可用选项及其默认值:
protected $signature = 'websockets:serve {--host=0.0.0.0} {--port=6001} {--disable-statistics : Disable the statistics tracking.} {--statistics-interval= : The amount of seconds to tick between statistics saving.} {--debug : Forces the loggers to be enabled and thereby overriding the APP_DEBUG setting.} {--loop : Programatically inject the loop.} ';启动成功后,终端会输出类似下面的提示:
Starting the WebSocket server on port 6001... Press Ctrl+C to stop the server值得注意的是,websockets:serve是一个前台常驻进程:它会一直占用当前终端,直到你按下Ctrl+C或进程收到终止信号。因此它非常适合在本地开发时直接运行,而在生产环境则通常交由 Supervisor 等进程守护工具托管(见下文「生产环境下的常驻运行」一节)。
更换监听端口:--port
WebSocket 服务器的默认端口是6001。如果你的 6001 端口已被占用,或出于安全、负载均衡的考虑需要换一个端口,可以通过--port选项指定:
php artisan websockets:serve --port=3030执行后,服务器将改为监听3030端口。
在更换端口时,需要同步修改以下三处配置,否则客户端将无法连接:
- 广播配置
config/broadcasting.php的pusher段中的port(通常写作env('PUSHER_APP_PORT', 6001)),Laravel 应用将事件推送到该端口; - 前端 Laravel Echo配置中的
wsPort,浏览器客户端从该端口建立 WebSocket 连接; - 如需访问调试面板,还需同步调整 config/websockets.php 中
dashboard.port(默认读取环境变量LARAVEL_WEBSOCKETS_PORT,默认值同样为6001)。
端口最终会传入 src/ServerFactory.php 的构造函数,由new Server("{$this->host}:{$this->port}", $this->loop)创建 ReactPHP 底层 Socket 服务(src/ServerFactory.php#L116)。
限制监听主机:--host
默认情况下,服务器监听0.0.0.0,即允许来自所有网络的连接。这在生产服务器上通常是需要的,但在本地开发或需要隔离网络访问时,你可能希望只允许特定来源的连接。
通过--host选项可以限制监听地址。例如,只允许本机连接:
php artisan websockets:serve --host=127.0.0.1这样 WebSocket 连接就只能来自 localhost,外部网络将无法访问。--host同样会与--port一起传入ServerFactory,组合成host:port的监听地址。常见的组合用法是:
# 在内网网卡上监听自定义端口 php artisan websockets:serve --host=192.168.1.100 --port=8080更多启动选项:源码级补充说明
原文档只介绍了--port与--host,但websockets:serve还提供了几个对运维和调试很有用的选项,它们都定义在命令签名中(src/Console/Commands/StartServer.php):
--debug:强制开启日志输出
服务器在应用处于 debug 模式(APP_DEBUG=true)时会自动在终端输出所有出入站的 WebSocket 事件日志。在生产环境(APP_DEBUG=false)下,日志默认关闭,此时可以使用--debug强制开启,便于排查线上问题:
php artisan websockets:serve --debug从源码看,configureHttpLogger、configureMessageLogger、configureConnectionLogger三个方法都会读取--debug选项,并用它覆盖app.debug配置(src/Console/Commands/StartServer.php#L220-L255)。日志类本身实现在 src/Server/Loggers 目录下,例如 src/Server/Loggers/WebSocketsLogger.php 会记录新连接建立、消息收发、连接关闭与异常信息。日志的详细输出效果可参考 docs/debugging/console.md。
--disable-statistics:关闭统计采集
如果不需要采集连接数、消息数等实时统计数据,可以加上该选项:
php artisan websockets:serve --disable-statistics对应源码位于configureStatistics()(src/Console/Commands/StartServer.php#L132-L143):当未传该选项时,命令会向事件循环注册一个周期定时器,每隔一段时间调用一次StatisticsCollectorFacade::save()落盘统计。
--statistics-interval:调整统计保存间隔
该选项以秒为单位指定统计数据的落盘周期,例如每 300 秒保存一次:
php artisan websockets:serve --statistics-interval=300未显式传入时,命令会读取配置websockets.statistics.interval_in_seconds(config/websockets.php 发布出来的默认值为60秒;若该配置项缺失,代码中回退值为3600秒)。
--loop:程序化注入事件循环
该选项主要面向测试与二次开发场景,允许外部注入一个 ReactPHP 事件循环实例(LoopInterface),而不是由命令内部自行创建。测试套件正是通过这种方式驱动命令的,见 tests/Commands/StartServerTest.php:
$this->artisan('websockets:serve', ['--loop' => $this->loop, '--debug' => true, '--port' => 6001]);命令内部做了什么:启动流程源码剖析
websockets:serve的handle()方法(src/Console/Commands/StartServer.php#L73-L94)按顺序执行一系列初始化,然后阻塞运行。理解这条调用链,有助于你判断启动异常时该去哪里排查:
- configureLoggers():注册 HTTP、消息、连接三类日志器,决定是否输出到终端;
- configureManagers():根据
websockets.replication.mode(local或redis)注册对应的ChannelManager单例。local模式使用数组在进程内保存连接(LocalChannelManager),redis模式则跨实例共享连接状态; - configureStatistics():按上述规则注册统计落盘定时器;
- configureRestartTimer():注册一个每 10 秒触发一次的定时器,轮询缓存键
beyondcode:websockets:restart,一旦发现该值发生变化就触发优雅重启(soft shutdown)。这就是websockets:restart命令能在最多 10 秒内重启服务器的底层机制; - configureRoutes():调用
WebSocketRouter::registerRoutes()注册内置路由。从 src/Server/Router.php 可以看到注册的路由包括 WebSocket 握手路由GET /app/{appKey}、Pusher HTTP API 路由(POST /apps/{appId}/events、GET /apps/{appId}/channels等)以及健康检查路由GET /health; - configurePcntlSignal():若 PHP 加载了
pcntl扩展,则为SIGTERM与SIGINT注册信号处理器,收到信号后优雅关闭所有现有连接再停止事件循环(src/Console/Commands/StartServer.php#L176-L198); - configurePongTracker():注册每 10 秒执行一次的定时器,调用
ChannelManager::removeObsoleteConnections()清理超时(失去心跳)的连接; - startServer():调用
buildServer()通过 src/ServerFactory.php 组装 RatchetIoServer并运行。
在组装服务器时(src/ServerFactory.php#L114-L133),ServerFactory还会做两件事:如果配置了websockets.ssl.local_cert,会用SecureServer包裹 Socket 以启用 WSS;同时会读取websockets.max_request_size_in_kb(默认250KB)作为 HTTP 请求体大小上限,传递给 src/Server/HttpServer.php。
生产环境下的常驻运行
websockets:serve是前台进程,必须保证它始终存活才能持续接受连接,因此生产环境普遍使用 Supervisor 托管(详见 docs/faq/deploying.md)。在/etc/supervisor/conf.d/websockets.conf(Debian/Ubuntu)中写入:
[program:websockets] command=/usr/bin/php /path/to/your/app/artisan websockets:serve numprocs=1 autostart=true autorestart=true user=www-data然后执行:
supervisorctl update supervisorctl start websockets进程崩溃后 Supervisor 会自动拉起。如果需要更新代码后优雅重启,可以发送websockets:restart信号(详见 docs/basic-usage/restarting.md):
php artisan websockets:restart该命令的实现只是向缓存写入当前时间戳(src/Console/Commands/RestartServer.php),服务器端每 10 秒轮询到变化后便会平滑重启,避免直接杀掉进程导致连接被粗暴断开。其行为由 tests/Commands/RestartServerTest.php 覆盖验证。
另外需要注意两点系统层面的限制:
- 文件描述符上限:Unix 系统默认每个进程最多打开 1024 个文件描述符,对应约 1024 个并发连接。可使用
ulimit -n 10000临时提升,或在/etc/security/limits.d/下写入laravel-echo soft nofile 10000永久生效; - 事件循环上限:默认基于
stream_select的事件循环硬限制为 1024 个并发连接,可通过安装ev或eventPECL 扩展更换事件循环来突破。
验证服务器是否成功启动
启动后可以从三个角度验证:
- 查看终端输出:正常启动会看到 "Starting the WebSocket server on port ..." 信息;开启 debug 后,每次新连接、每条消息都会实时打印(docs/debugging/console.md);
- 请求健康检查端点:服务器内置了
GET /health路由(src/Server/Router.php),可以直接用 curl 探测:
curl http://127.0.0.1:6001/health- 测试用例参考:仓库的 tests/Commands/StartServerTest.php 展示了在测试环境中启动服务器并验证
SIGINT/SIGTERM软关闭行为的完整写法,可以作为你集成测试的模板。
小结
php artisan websockets:serve是整个 Laravel WebSockets 包的使用入口:默认监听0.0.0.0:6001,通过--port可更换端口、通过--host可限制监听网卡,配合--debug、--disable-statistics、--statistics-interval等选项可以精细控制运行行为。理解了handle()内部的事件循环、定时器、路由注册与信号处理机制之后,你既能自信地在本机跑通第一条 WebSocket 连接,也能从容地把服务稳定地部署到生产环境。
- 后端
- 即时通讯
【免费下载链接】laravel-websockets
Websockets for Laravel. Done right.
相关推荐
CoreDNS bind 插件详解:精确控制 DNS 服务器监听地址与接口绑定
CoreDNS bind 插件详解:精确控制 DNS 服务器监听地址与接口绑定 导读 bind 是 CoreDNS 中用于覆盖服务器默认监听地址的插件。默认情况
后端网络云原生在 Laravel Sail 中运行 Laravel WebSockets:端口转发配置与实战指南
在 Laravel Sail 中运行 Laravel WebSockets:端口转发配置与实战指南 Laravel WebSockets 为 Laravel 应
后端即时通讯XHS-Downloader中服务监听地址的优化与改进
XHS Downloader中服务监听地址的优化与改进 在XHS Downloader项目的开发过程中,服务监听地址的配置经历了一次重要的优化调整。本文将详细分
网页爬虫
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考