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

Gatewayclient Laravel Package

workerman/gatewayclient

GatewayClient is a lightweight PHP client for Workerman's GatewayWorker that lets any PHP application push messages to connected WebSocket clients. Send to a single client, a group, or broadcast to everyone, plus check online status and kick connections—no framework dependency required.

View on GitHub
Deep Wiki
Context7

Getting Started

workerman/gatewayclient is not a Laravel package — it's a thin, static PHP SDK that lets a normal PHP process (your Laravel app) talk to a running GatewayWorker server over its internal text/binary protocol. It is only useful if you already run a GatewayWorker cluster (Register + Gateway + BusinessWorker processes). If you just need WebSockets with Laravel, use Reverb/Pusher first; reach for this when you're operating Workerman yourself.

Minimal steps

  1. Require it:
    composer require workerman/gatewayclient
    
  2. Have a GatewayWorker running. The Register service (default 127.0.0.1:1236) is what the client dials by default.
  3. Point the client at your Register before any call is made:
    use GatewayClient\Gateway;
    
    Gateway::$registerAddress = '127.0.0.1:1236';
    Gateway::$secretKey = config('gateway.secret_key'); // must match GatewayWorker
    
  4. Send your first message from a controller:
    Gateway::sendToUid($user->id, json_encode(['event' => 'ping']));
    

Where to look first

  • src/Gateway.php — the whole API lives here; read the static method list (~25 methods) rather than the README, which is terse.
  • README's config block for $registerAddress, $secretKey, $connectTimeout, $timeout.
  • Your GatewayWorker's Events.php — the UID/group bindings that make sendToUid work are created there (or via Gateway::bindUid).

First use case: authenticated user notifications. User logs in over WebSocket, your BusinessWorker binds their connection to a UID, and your Laravel controller pushes to that UID over HTTP.

Implementation Patterns

1. Configure once, in a service provider. The class uses static global state; setting $registerAddress late (after the first call) has no effect because the connection is cached. Use boot():

public function boot(): void
{
    Gateway::$registerAddress = config('gateway.register');
    Gateway::$secretKey       = config('gateway.secret_key');
    Gateway::$connectTimeout  = 1;
    Gateway::$timeout         = 2;
}

2. Wrap it behind a service, not raw static calls. Create App\Realtime\GatewayClient implementing a small interface so controllers/jobs don't depend on a global. This is also your mocking seam for tests.

class RealtimeGateway
{
    public function toUser(int|string $uid, array $payload): void
    {
        $ok = Gateway::sendToUid($uid, json_encode($payload));
        if ($ok === false) {
            Log::warning('gateway send failed', ['uid' => $uid]);
        }
    }
}

3. Bind UIDs where you control the connection. Two valid flows:

  • Worker-side (preferred): Events::onConnect/onMessage validates a token and calls Gateway::bindUid($clientId, $uid) inside the worker.
  • App-side: after login, Gateway::bindUid($clientId, $uid) from Laravel — but you must already know the clientId, which you only get from the browser or from Gateway::getClientIdByUid().

4. Use groups for rooms/topics, but rejoin on reconnect. joinGroup/leaveGroup/sendToGroup map nicely to chat rooms and channel subscriptions. Group membership is in-memory: the client must rejoin after every reconnect, so drive joins from onConnect in the worker, not from the browser.

5. Enqueue non-critical broadcasts. sendToAll and sendToGroup are one socket write each, but a loop over 5,000 users is 5,000 round trips. Push that into a queued job:

SendBroadcast::dispatch($channelId, $payload)->onQueue('realtime');

6. Query presence from HTTP. Gateway::isUidOnline($uid), getClientIdByUid, getAllClientIdCount, getAllUidCount are legitimate for "who's online" widgets, typing indicators, and deciding whether to send an email fallback. Cache results for a few seconds — each is a synchronous round trip.

7. Health check. A tiny artisan command that calls Gateway::getAllClientIdCount() and alerts on false catches a dead Register before users report missing messages.

8. Testing. Bind the interface in the container to a fake recorder in TestCase::setUp; never let unit tests dial 1236.

Gotchas and Tips

  • Silent failures. Most methods return false on a dead socket rather than throwing. Always check the return or wrap in your own helper that logs — otherwise outages look like "the UI just doesn't update."
  • Static config ordering. $registerAccessKey/$secretKey and $registerAddress must be set before the first Gateway:: call. In Octane or long-running queue workers, a later config() change won't apply. Reset with Gateway::closeConnection() if you must reconfigure.
  • Connecting to a Gateway instead of the Register works, but then broadcasts only reach clients on that Gateway. Use the Register address unless you have a specific reason.
  • UID is not unique per connection. getClientIdByUid returns an array — a user in two tabs has two client IDs. sendToUid handles this; your own lookups must too.
  • Secret key mismatches fail opaquely. If GatewayWorker is started with --secretKey, the client must use the identical value or the connection is dropped with no useful error.
  • Socket timeouts are global. Keep $connectTimeout low (1s) so a dead Register doesn't hang HTTP requests. Because the connection is process-static, a stale socket after a Register restart can fail calls until you reconnect — add a retry-once wrapper in your service.
  • Payload size. The protocol length header allows large messages, but GatewayWorker and your BusinessWorker memory limits don't. Keep frames small and JSON-encoded; send IDs and re-hydrate client-side for anything heavy.
  • Not for high-frequency writes. Sends are synchronous syscalls from the PHP process. If you're pushing per-row in a loop inside a DB transaction, you're blocking on the socket — batch or queue.
  • No Laravel facade, no config publish. Everything (config file, facade, DTOs) is yours to write; keep the config file thin (register, secret_key, timeout) and read env vars.
  • Version pairing. The 2025 release targets Workerman 4/5 and GatewayWorker 3.x+. Pin the major version in composer.json and upgrade GatewayWorker and GatewayClient together.
  • Never expose the Register port. It has no authentication beyond the shared secret and grants full messaging control; keep it on the private network and out of docker-compose published ports.
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.
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
nodisrupt/laravel-agent
sierratecnologia/media-manager