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

Phpws Laravel Package

mpociot/phpws

mpociot/phpws is a lightweight, event-driven WebSocket server for PHP built on ReactPHP. Simple onOpen, onMessage, and onClose callbacks make it easy to add real-time features like chat, notifications, and live updates to your apps.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit — a second runtime, and that is the decision. mpociot/phpws is a ReactPHP-based WebSocket server and client that runs as a single-threaded, long-lived event-loop daemon. It is categorically outside Laravel's PHP-FPM request/response lifecycle: it cannot be mounted as a route, a controller, or a queue worker. Adopting it means the platform team owns a new deploy topology unit to supervise, monitor, and page on. The TPM's first gate is therefore a requirements gate, not a code review: does the roadmap genuinely require a persistent socket tier (live notifications, chat, presence, live dashboards), or can SSE, polling, or managed pub/sub deliver the same product outcome? If a socket tier is real and the org accepts a second runtime, fit is moderate. If the need is "push a few browser updates," fit is weak and a managed service or Laravel Reverb is structurally better. Verdict: spike vehicle and reference implementation, not a production default.

Integration feasibility — everything around the socket is bespoke glue. There is no service provider, no broadcasting driver, no config publishing, no handshake auth hooks, no queue integration. The library gives event callbacks (onOpen, onMessage, onClose) and a working loop; everything a Laravel application actually needs is ours to design and own:

  • An artisan ws:serve command to launch and manage the daemon.
  • A process supervisor unit (systemd/Supervisor) with restart and backoff policy.
  • A TLS-terminating reverse proxy in front of the daemon.
  • Handshake authentication inside onOpen (session cookie or JWT verification) — no middleware pipeline exists to reuse.
  • A channel model plus authorization rules: who may subscribe to what, and where that check executes.

None of this appears in the "lightweight, framework-agnostic, minimal setup" pitch, and all of it belongs in the estimate before commitment. Feasible as a 1–2 week bounded spike; multi-week work before production traffic, and that estimate precedes any scaling effort.

Technical risk — high, concentrated, and nameable. The TPM's job is to put each item in the register before someone discovers it in a security review:

  • Abandonment. Last release May 2019, 28 stars, zero dependents. No security patches, no PHP 8.x guarantees, no current ReactPHP support. Any CVE on the socket, TLS, or event-loop path routes directly to this team.
  • Dependency pinning. ReactPHP 7.x-era constraints will likely collide with a modern Laravel/Octane lockfile; expect composer why-not fights and possible dead ends before the first line of product code.
  • Concurrency ceiling. A synchronous call inside a handler — an Eloquent query, an outbound HTTP request — stalls all connections, not one. This is routinely underestimated and is a classic post-launch incident source.
  • Zero ecosystem signal. No dependents means no community debugging surface. Every incident is diagnosed solo, inside the team, under time pressure.
  • Security posture. Network-facing code with no patches since 2019 is a review finding. Expect the gate closed unless blast radius is strictly internal.

Key questions to close before approving.

  1. What is the concrete real-time requirement, and is a socket tier mandatory versus SSE, polling, or managed pub/sub?
  2. What PHP and Laravel versions are targeted — does it install against the current lockfile at all, and does it coexist with Octane?
  3. Who owns the daemon in production — platform or application — and is that headcount funded and on-call?
  4. Does the product need horizontal scale (multiple socket nodes) at launch? If yes, this package has no clustering story and none will arrive.
  5. If a CVE or PHP upgrade breaks it, are we prepared to fork and maintain — with a named owner and a funded time budget?

Integration Approach

Stack fit — the canonical seam is portable, which is the whole argument. The correct pattern is Laravel publishing domain events to Redis and a standalone WS daemon subscribing and fanning out to connected sockets. That seam is identical regardless of library. Because it is portable, the auth, TLS, proxy, and supervisor work invested during the spike survives a swap untouched — which is precisely why picking a maintained daemon is the rational default and this one is prior art.

Migration path — abstract first, spike second, swap third. Sequence defensively so the library decision stays reversible:

  1. Abstract the transport before any code touches phpws. Define an internal Broadcaster interface (channel subscribe, message publish, presence track) with no library types leaking into domain code. This is the single highest-value TPM decision in the effort: it converts a risky dependency into a bounded experiment with a clean, pre-agreed exit, and makes every later transport swap a configuration change rather than a rewrite.
  2. Spike, timeboxed and labeled. Stand up phpws behind artisan ws:serve to prove the real-time UX and client behavior end to end. Non-production, no hardening, written acceptance criterion, explicit stop date, named owner.
  3. Swap before production traffic. Replace the daemon with Laravel Reverb (first-party) or Soketi. Auth, proxy, TLS, and supervisor work carries over unchanged, so nothing from step 2 is wasted spend.

Compatibility — verify before writing product code. Clean install on PHP 8.2/8.3; ReactPHP constraint resolution against the current lockfile; Octane interaction, where the daemon must run as a separate process and never inside an Octane worker. Assume TLS termination, CORS/origin checks, handshake auth, and channel authorization are entirely absent and must be built. Treat the client side as unvalidated too: no reconnect/backoff, no heartbeat, no message ordering guarantees ship in the box.

Sequencing gates. Gate 1: requirements gate (socket tier justified). Gate 2: Broadcaster interface merged. Gate 3: compatibility spike passes install and Octane separation. Gate 4: demo acceptance criterion met. Gate 5: maintained target approved and funded in the same decision, so the swap is scheduled work rather than a contingency discovered mid-build.

Operational Impact

Maintenance — we own it outright the day it ships. No upstream to escalate to, no release cadence to ride. If it is vendored, it needs a version pin, a security review, a named maintainer, and an explicit recurring time budget for patching. Frame it plainly: cheapest to prototype, most expensive to own.

Support — no safety net. Zero dependents means zero community debugging surface; every incident is diagnosed inside the team under time pressure, with no changelog to consult. That cost is invisible in the spike and permanent in production, and it should be stated in those terms in the risk register rather than discovered later.

Scaling — single process, no clustering story, none arriving. Horizontal scale requires the Redis publish/fan-out pattern plus sticky routing, connection accounting, and backpressure handling the library does not provide. Long-running event loops accumulate memory and require recycling discipline. The TPM decision is to declare the launch scale assumption up front: if multi-node fan-out is a launch requirement, this package is disqualified on day one.

Failure modes to write into the runbook before the spike ends.

  • A blocking handler (Eloquent, outbound HTTP) stalls every connection — the highest-probability, highest-severity incident.
  • Memory growth in the long-lived loop degrading performance without an obvious error signal.
  • Ungraceful restarts dropping all clients with no reconnect logic on the client side.
  • TLS proxy or origin misconfiguration presenting as "WebSockets just don't connect."
  • Supervisor restart storms masking an underlying crash loop.
  • Silent half-open connections with no heartbeat detection.
  • Auth bypass via a missed onOpen path — the security-relevant failure, and the reason a handshake check belongs in the threat model, not the backlog.

Ramp-up — the hidden workstream. The "pure PHP, easy integration" pitch understates the onboarding tax: an artisan ws:serve command, a supervisor with restart policy, a TLS-terminating proxy, handshake authentication, channel authorization, heartbeat, and event-loop discipline. Estimate it as multi-week before any scaling, gate the spike with an explicit acceptance criterion so it cannot quietly become production, and prefer maintained alternatives that reuse Laravel's broadcasting and auth conventions when the team lacks async/event-loop experience.

Decisions requested: approve the timeboxed spike; approve the Broadcaster abstraction as a build constraint on the spike; and approve the maintained production target now so the swap is scheduled, funded work rather than a contingency we rediscover at launch.

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.
skyraptor/chatter
edlugz/sasapay
abbasudo/artisan-route
mirvan/ippanel
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource