onveyor
Site menu
GitHub
Introduction / Quick Start Native mode

Quick Start

Start a native Socket Conveyor server, connect two WebSocket clients, and verify a channel broadcast.

This guide runs native Conveyor with your own PHP entrypoint. Complete the PHP package setup first. For a packaged Pusher/Reverb server without local OpenSwoole installation, use the Docker setup and the Laravel Echo / Reverb guide.

1Create the server

Create server.php:

server.phpnative
<?php

use Conveyor\Constants;
use Conveyor\ConveyorServer;

require __DIR__ . '/vendor/autoload.php';

(new ConveyorServer())
    ->host('127.0.0.1')
    ->port(8989)
    ->serverOptions([
        'worker_num' => 1,
        'task_worker_num' => 1,
    ])
    ->conveyorOptions([
        Constants::WEBSOCKET_SUBPROTOCOL => Constants::SOCKET_CONVEYOR,
        Constants::USE_PRESENCE => false,
        Constants::USE_ACKNOWLEDGMENT => false,
    ])
    ->start();

2Run it

shell
php server.php

ConveyorServer::start():

Initializes default persistence tables Creates an OpenSwoole WebSocket server Selects the configured subprotocol Starts listening

3Connect two clients

Keep php server.php running. Save the following as client.html, open it in two browser tabs (A and B), and open Developer Tools → Console in each tab. Both tabs must stay open.

client.htmlnative
<!doctype html>
<title>Conveyor test client</title>
<p>Open the browser console to test messages.</p>
<script>
  const ws = new WebSocket('ws://127.0.0.1:8989')

  ws.onmessage = event => {
    console.log('received', event.data)
  }
  ws.onerror = () => console.error('WebSocket error: check the server and URL')
  ws.onclose = event => console.log('closed', event.code, event.reason)

  ws.onopen = () => {
    ws.send(JSON.stringify({
      action: 'channel-connect',
      channel: 'chat.room.1',
    }))
    console.log('channel-connect sent for chat.room.1')
  }
</script>

In both consoles, wait for channel-connect sent for chat.room.1 and a received connection-info message. The log confirms that the join request was sent; it is not a server acknowledgment of channel membership.

4Verify the broadcast

After both clients have connected, run this in tab A’s console:

tab A · browser console
ws.send(JSON.stringify({
  action: 'broadcast-action',
  data: { body: 'hello' },
}))

Tab B’s console should log received followed by JSON like this (field order may vary):

tab B · expected message
{
  "action": "broadcast-action",
  "data": { "body": "hello" },
  "fd": 1
}

fd identifies the sending socket; its number may differ from 1. Seeing data.body equal to hello in tab B confirms delivery. Tab A does not receive its own broadcast. You can run the same send command in tab B to check delivery back to tab A.

If no message arrives

  • If either tab has no connection-info, check that the PHP server is running and both clients use ws://127.0.0.1:8989 on the same machine as the server. Inspect the browser console and server terminal for errors.
  • Check ws.readyState === WebSocket.OPEN in both consoles. If false, reload that client after starting the server.
  • Make sure both clients send channel-connect with exactly chat.room.1. If the first broadcast was sent while the other tab was still joining, send it again after both tabs are ready.
  • Look in the receiving tab’s console. Broadcasts go to other sockets in the channel, so the sender’s console alone cannot confirm delivery.
  • If adapting this example to an HTTPS page, use a TLS-enabled wss:// endpoint; browsers block insecure WebSocket connections from secure pages.

5Go further

Prefer a packaged native client? See the JavaScript and PHP client guides.