Weave Code
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

Web Socket Bundle Laravel Package

oroinc/web-socket-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require gos/web-socket-bundle
    

    Add to config/bundles.php:

    return [
        // ...
        Gos\WebSocketBundle\GosWebSocketBundle::class => ['all' => true],
    ];
    
  2. Configure WebSocket Server: Update config/packages/gos_web_socket.yaml:

    gos_web_socket:
        server:
            port: 8080
            host: 0.0.0.0
            clients_max: 1000
        routing:
            default_route: 'app.websocket.default'
    
  3. First Use Case: Create a WebSocket route in a controller:

    use Gos\Bundle\WebSocketBundle\Annotation\Route;
    use Gos\Bundle\WebSocketBundle\Annotation\WebSocket;
    
    class ChatController
    {
        /**
         * @Route("/chat", name="app.websocket.chat")
         * @WebSocket("chat")
         */
        public function onChatConnection(\Gos\Bundle\WebSocketBundle\WebSocket\ClientInterface $client)
        {
            $client->send(json_encode(['type' => 'connection', 'message' => 'Welcome!']));
        }
    }
    
  4. Run the Server:

    php bin/console gos:websocket:start
    
  5. Test with JavaScript:

    const socket = new WebSocket('ws://localhost:8080/chat');
    socket.onmessage = (event) => console.log(event.data);
    

Implementation Patterns

Common Workflows

  1. Real-Time Messaging:

    • Use @WebSocket annotations to define event handlers for connection, message, and disconnection.
    • Example:
      /**
       * @WebSocket("chat.message")
       */
      public function onChatMessage(\Gos\Bundle\WebSocketBundle\WebSocket\ClientInterface $client, $data)
      {
          $message = json_decode($data, true);
          $this->broadcastToAll('chat', json_encode(['type' => 'message', 'content' => $message['content']]));
      }
      
  2. Broadcasting to Specific Clients:

    • Store client IDs in a database or Redis and target them:
      $this->broadcastTo(['client_id_1', 'client_id_2'], 'chat', json_encode(['type' => 'alert']));
      
  3. Authentication:

    • Validate clients via middleware or route parameters:
      /**
       * @Route("/private-chat/{token}", name="app.websocket.private_chat")
       * @WebSocket("private_chat")
       */
      public function onPrivateChat(\Gos\Bundle\WebSocketBundle\WebSocket\ClientInterface $client, $token)
      {
          if (!$this->validateToken($token)) {
              $client->close();
              return;
          }
          // Proceed...
      }
      
  4. Integration with Symfony Events:

    • Dispatch Symfony events for cross-cutting concerns (e.g., logging):
      use Symfony\Component\EventDispatcher\EventDispatcherInterface;
      
      public function __construct(private EventDispatcherInterface $dispatcher) {}
      
      /**
       * @WebSocket("chat.connection")
       */
      public function onConnection(\Gos\Bundle\WebSocketBundle\WebSocket\ClientInterface $client)
      {
          $this->dispatcher->dispatch(new WebSocketConnectionEvent($client));
      }
      

Integration Tips

  1. Frontend Integration:

    • Use Autobahn|JS for advanced WebSocket features (e.g., reconnection logic).
    • Example with Vue.js:
      import { WebSocket } from 'autobahnjs';
      
      const connection = new WebSocket('ws://localhost:8080/chat');
      connection.onopen = () => connection.send(JSON.stringify({ type: 'join', user: 'Alice' }));
      
  2. Load Balancing:

    • Use a reverse proxy (e.g., Nginx) to distribute WebSocket connections:
      location /ws {
          proxy_pass http://websocket_server:8080;
          proxy_http_version 1.1;
          proxy_set_header Upgrade $http_upgrade;
          proxy_set_header Connection "Upgrade";
      }
      
  3. Scaling:

    • Deploy multiple WebSocket servers behind a load balancer and use Redis for pub/sub to sync messages across instances.
  4. Testing:

    • Use Gos\Bundle\WebSocketBundle\Tests\WebSocketTestCase for unit/integration tests:
      public function testChatConnection()
      {
          $client = $this->createMockClient();
          $this->assertSame('Welcome!', $this->getController()->onChatConnection($client));
      }
      

Gotchas and Tips

Pitfalls

  1. CORS Issues:

    • Ensure your WebSocket server and frontend are configured to allow cross-origin requests. Add CORS headers in your proxy or use the cors option in the bundle config:
      gos_web_socket:
          server:
              cors_origin: ["http://localhost:3000"]
      
  2. Connection Limits:

    • Default clients_max is 1000. Increase if needed, but monitor memory usage:
      gos_web_socket:
          server:
              clients_max: 5000
      
  3. PHP-FPM vs. CLI:

    • The WebSocket server runs in CLI mode. Ensure your PHP CLI has the same extensions enabled as your web server (e.g., pdo_mysql).
  4. Route Conflicts:

    • Avoid naming WebSocket routes the same as HTTP routes. Use unique prefixes (e.g., ws.chat).
  5. Memory Leaks:

    • Unbounded client connections can exhaust memory. Implement client timeouts or use a connection manager:
      $client->setTimeout(30); // Close after 30 seconds of inactivity
      

Debugging

  1. Logs:

    • Enable debug mode in gos_web_socket.yaml:
      gos_web_socket:
          debug: true
      
    • Check logs at var/log/gos_websocket.log.
  2. Common Errors:

    • Connection refused: Verify the port is open and not blocked by a firewall.
    • Invalid route: Ensure the route is annotated with @WebSocket and matches the bundle config.
    • JSON decode error: Validate payloads on the client side before sending.
  3. Tooling:

    • Use tcpdump or Wireshark to inspect WebSocket traffic:
      tcpdump -i any port 8080 -w websocket.pcap
      

Extension Points

  1. Custom Handshake:

    • Override the default handshake logic by extending Gos\Bundle\WebSocketBundle\WebSocket\Server\Server:
      class CustomServer extends Server
      {
          protected function onHandshake($resource, $key)
          {
              // Custom logic (e.g., validate API keys)
              return parent::onHandshake($resource, $key);
          }
      }
      
    • Register the custom server in services.yaml:
      services:
          Gos\Bundle\WebSocketBundle\WebSocket\Server\Server:
              class: App\WebSocket\CustomServer
      
  2. Middleware:

    • Add middleware for request/response processing:
      use Gos\Bundle\WebSocketBundle\WebSocket\MiddlewareInterface;
      
      class AuthMiddleware implements MiddlewareInterface
      {
          public function onMessage(\Gos\Bundle\WebSocketBundle\WebSocket\ClientInterface $client, $message)
          {
              if (!$this->isAuthenticated($message)) {
                  $client->close();
              }
              return $message;
          }
      }
      
    • Register in services.yaml:
      services:
          Gos\Bundle\WebSocketBundle\WebSocket\Middleware\AuthMiddleware:
              tags: ['gos_websocket.middleware']
      
  3. Event Subscribers:

    • Listen to WebSocket events globally:
      use Gos\Bundle\WebSocketBundle\Event\WebSocketEvent;
      
      class WebSocketSubscriber implements EventSubscriberInterface
      {
          public static function getSubscribedEvents()
          {
              return [
                  WebSocketEvent::CONNECTION => 'onConnection',
                  WebSocketEvent::MESSAGE => 'onMessage',
              ];
          }
      
          public function onConnection(WebSocketEvent $event) { /* ... */ }
      }
      
  4. Custom Protocols:

    • Extend the bundle to support custom subprotocols:
      class CustomProtocol extends \Gos\Bundle\WebSocketBundle\WebSocket\Protocol\Protocol
      {
          public function encode($data) { /* ... */ }
          public function decode($data) { /* ... */ }
      }
      
    • Register in services.yaml:
      services:
          Gos\Bundle\WebSocketBundle\WebSocket\Protocol\Protocol:
              class: App\WebSocket\Custom
      
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.
besmartand-pro/php-quality-config
sentix/ai-chatbot
terminal42/code-quality-tools
codifyo/ts-generator-bundle
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity