Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Gateway Worker Laravel Package

workerman/gateway-worker

GatewayWorker is a PHP distributed framework built on Workerman for long-lived TCP, UDP, and WebSocket connections. It separates gateway, business worker, and register processes to scale real-time apps across servers, with process management and messaging for chat, IoT, push, and game backends.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Verdict: GatewayWorker is a credible, actively maintained (release 2025-06-27, MIT) distributed socket framework, but it is a process-level infrastructure component, not a Laravel package. For a Laravel-centric roadmap it is a build decision that creates a permanently separate runtime, not an install decision. The 21.6 score and zero Composer dependents reflect this: the ecosystem consumes GatewayWorker by cloning the distribution, not by composer require, so we inherit unfashionable supply-chain and versioning characteristics.

Architecture fit

  • GatewayWorker is a three-role topology: Gateway (holds client sockets, speaks the wire protocol), Register (service discovery between processes/hosts), BusinessWorker (application logic). Only BusinessWorker is our code; the other two are opaque runtime.
  • It assumes a long-running, multi-process CLI daemon with pcntl/posix and ideally ext-event. Laravel's request lifecycle (FPM/Octane-per-request, container-per-request, Request facade, session, CSRF, middleware stack) does not exist in that model. Anything stateful in Laravel must be re-derived manually.
  • Fit is good for: high concurrent-connection counts (tens of thousands per host), custom/private TCP or UDP protocols, IoT device fleets, binary framing, and cases where per-connection cost matters. Fit is poor for: standard Laravel feature work, teams without socket-operations experience, and anything needing delivery guarantees.

Integration feasibility

  • Feasible and well-trodden: run GatewayWorker under Supervisor on the same VPC as Laravel, and bridge with Redis pub/sub or a queue. BusinessWorker publishes to Redis; Laravel listens/subscribes and pushes. Client→server messages get validated in BusinessWorker and handed to Laravel via queue or internal HTTP.
  • Bootstrapping the Laravel container inside BusinessWorker is technically possible (initialize Illuminate once at worker start) but is an anti-pattern at scale: it couples socket availability to Eloquent/queue health, and any blocking call stalls every connection on that worker.
  • No Laravel auth, no Sanctum/Passport handshake, no rate limiting, no validation, no broadcasting driver. All of it is custom code we own. There is no first-party Laravel broadcast driver for GatewayWorker, so ShouldBroadcast events will not reach it without a bespoke bridge.

Technical risk

  • Blocking-I/O head-of-line stalls (high). Workerman is single-threaded per process; a synchronous DB query or HTTP call in BusinessWorker freezes that worker's entire connection set. Architecturally我们必须 enforce an async-only discipline.
  • Unbounded memory growth (high). Long-lived processes accumulate state; leaks manifest as OOM after days, not in staging. Requires soak testing and periodic graceful worker recycling — a capability the framework does not give us for free.
  • No delivery semantics (high). Fire-and-forget by default: no ack, no persistence, no reconnect replay, no ordering guarantee. Any product requirement like "user must not miss messages" becomes a Redis Streams/queue redesign on our side, not a config flag.
  • Register as a soft SPOF / discovery drift (medium). Multi-host deployments depend on Register reachability; stale registrations and half-open Gateway↔BusinessWorker links are the classic operational failure.
  • Supply chain and versioning (medium). Zero Composer dependents means little ecosystem pressure on semver, security advisories, or CVE response. Vendored distributions drift silently from upstream.
  • Competitive substitution risk (medium-high). Laravel Reverb (first-party, Pusher-protocol, Laravel-native auth/broadcasting), Soketi, Centrifugo, and Swoole/OpenSwoole stacks cover most of the same ground with far better framework ergonomics. Choosing GatewayWorker is a deliberate bet on raw connection economics or protocol flexibility over integration cost.

Key questions for the technical discovery

  1. What is the actual concurrent-connection and message-per-second target? Below ~5–10k connections with a Pusher-protocol need, Reverb is the cheaper answer.
  2. Do we need a non-WebSocket protocol (raw TCP/UDP, binary framing, device heartbeats)? This is GatewayWorker's strongest differentiator.
  3. Is at-least-once delivery, ordering, or offline replay in scope? If yes, budget a persistence layer.
  4. Who owns 24/7 socket operations — do we have (or hire) someone fluent in event-loop debugging?
  5. Can we terminate TLS at the load balancer and use WSS only, avoiding per-process certificate handling?
  6. What is the graceful-deploy story (worker reload vs. connection drop) and is brief disconnection acceptable to the product?
  7. PHP version alignment: the Workerman v4 line supports PHP 7.x, v5 requires PHP 8.1+; confirm against our Laravel version's floor and pin explicitly.

Integration Approach

Stack fit

  • Treat GatewayWorker as a sidecar service, not an application dependency. Laravel remains the system of record, auth authority, and HTTP API; GatewayWorker owns only the socket layer and ephemeral presence state.
  • Recommended boundary: Redis as the message bus (pub/sub for fan-out, Streams if replay is required) plus a dedicated realtime queue connection for Laravel→BusinessWorker work. Avoid direct HTTP between Laravel and BusinessWorker on the hot path.
  • Auth pattern: client connects → GatewayWorker forwards handshake to Laravel (or validates a short-TTL signed JWT issued by Laravel) → connection is bound to user_id/tenant_id in Redis with a TTL heartbeat. Never trust a client-supplied identity after handshake.
  • Deploy in the same private network/VPC as Laravel; one load balancer with sticky routing is not required (Register handles placement), but WSS termination and connection draining at the LB are.

Migration path

  1. Spike (1–2 weeks): stand up GatewayWorker behind nginx on a single host with 2 Gateway / 2 BusinessWorker processes; wire a Redis bridge to a Laravel event; prove auth handshake, presence, and a broadcast to 1k simulated connections (use wscat/k6/Artillery).
  2. Shadow mode (2–4 weeks): mirror an existing polling/SSE feature to GatewayWorker without cutting over; compare latency, delivery counts, and memory curves over a 72-hour soak.
  3. Cutover by feature, not by platform: migrate one low-blast-radius feature (notifications) before chat/presence. Keep the polling path as a fallback behind a flag for one release cycle.
  4. Decommission the old path only after a full business cycle of zero fallbacks.

Compatibility

  • Hard requirements: Linux only (Windows unsupported), PHP CLI with pcntl + posix, ext-event strongly preferred over the default select loop for >1k connections. This may not match our app servers' PHP build — plan a separate runtime image.
  • Pin the Workerman major version and the GatewayWorker tag explicitly in a lockfile or submodule; do not track master.
  • No PHP-FPM, no Apache mod_php, no shared hosting, no serverless. Confirm our platform does not assume any of these.
  • Laravel Octane/Swoole coexistence is fine but redundant — do not run both for the same traffic; pick one realtime runtime.

Sequencing (TPM view)

Phase Deliverable Exit criteria
0 ADR comparing GatewayWorker vs. Reverb vs. Centrifugo Written decision with connection-cost model
1 Runtime image + Supervisor config + CI smoke test Deploys via existing pipeline, not SSH
2 Auth handshake + presence + Redis bridge Pen-test pass, token expiry verified
3 Shadow traffic + 72h soak Memory flat, p99 handshake < 300ms
4 Feature cutover behind flag Rollback rehearsed and timed
5 Runbooks, dashboards, on-call handover SLOs defined and alerting live

Budget explicitly for the bridge and auth layer — in our experience this is 60–70% of the total effort, and none of it ships with the package.


Operational Impact

Maintenance

  • Two release cadences to track: our Laravel app and the socket service. They must be independently deployable and independently rollback-able; a shared deploy unit is the single most common way this architecture degrades into "we can't ship on Fridays."
  • Upstream is a single-maintainer project. Bus-factor risk is real: plan to vendor the distribution, read the changelog on every bump, and keep an internal fork path warm. MIT license makes forking legal; it does not make it cheap.
  • Config lives in PHP files and Supervisor units, not .env/Laravel config. Duplicate source-of-truth for ports, hosts, and Redis DSNs is a recurring drift source — centralize via a generated config artifact at deploy time.

Support

  • Existing Laravel tooling does not see this service: no Telescope, no Horizon, no Laravel logs, no exception handler, no Sentry integration out of the box. Every observability signal is custom-built — structured logs to stdout, a /metrics or status endpoint on the Gateway (connection counts, per-worker memory), and error forwarding into our existing Sentry/log stack.
  • On-call must learn a new failure vocabulary (Gateway down vs. BusinessWorker down vs. Register unreachable) — each presents to users as "messages stopped," which is indistinguishable without good dashboards. Budget for a decision tree in the runbook.

Scaling

  • Horizontal scale is a genuine strength: add BusinessWorker processes for CPU, add Gateway processes for connection count, add hosts for both, with Register handling discovery. This is where the framework earns its keep.
  • Scale is capped by shared state, not by the framework: presence, room membership, and fan-out must live in Redis. Redis becomes the real scaling bottleneck and the real availability dependency — size and monitor it accordingly.
  • Practical guidance: 2–4 Gateway processes per core-bound host for I/O, BusinessWorker count tuned to CPU, and never co-locate business logic that blocks. Plan a connection-count ceiling per host and load-test to it before launch, not after.
  • Cost profile is attractive versus per-connection SaaS (Pusher/Ably) above roughly a few thousand concurrent connections; below that, the operational overhead dominates and SaaS is cheaper in total cost.

Failure modes to instrument and rehearse

Failure User-visible symptom Mitigation
BusinessWorker blocking on DB/HTTP All connections on that worker stall silently Async-only code review gate; per-worker memory + event-loop-lag alerts
Memory leak / gradual OOM Random disconnects after days of uptime Weekly graceful reload; memory ceiling alarm; soak test in CI
Register unreachable New Gateways can't find workers; partial outages Redundant Register; health check that exercises discovery, not just TCP
Redis outage Auth failures, no cross-node fan-out, presence lost Redis HA; fail-closed for auth, fail-open for non-critical presence
Deploy without drain Mass disconnect storm, client reconnect stampede LB connection draining + graceful worker stop; jittered client backoff
No delivery guarantee Silent message loss under load Product-level decision: accept, or build Redis Streams replay
Token/auth bypass Security incident Signed short-TTL tokens, origin checks, per-connection rate limits

Ramp-up

  • Realistic ramp: 2–3 weeks for a senior PHP engineer already comfortable with async/event-loop concepts to be productive; 4–6 weeks to be genuinely on-call-capable. Engineers whose entire model is request/response will fight the framework and write blocking code; assume one blocked-afternoon-per-engineer plus a formal code review checklist for anything touching BusinessWorker.
  • The scarcest skill is debugging a hung event loop in production — this is not a Laravel skill. Identify that person before committing, or accept a longer mean-time-to-recovery.
  • Documentation debt is high: our bridge, auth handshake, presence model, and message envelope are all bespoke and all undocumented by upstream. Treat internal docs and a load-test harness as day-one deliverables, not follow-ups.
  • Recommendation: proceed only if the connection-scale or protocol-flexibility case is concrete and quantified. If the requirement is "Laravel app needs WebSockets," Laravel Reverb wins on integration cost, observability, and hiring by a wide margin — and this package's 21.6 opportunity score already prices in that gap.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core