walkor/phpsocket.io
walkor/phpsocket.io has 2,340 GitHub stars and 503 forks. GitHot measured 0 stars in 24 hours. Last checked 2026-11-07 21:53 UTC. Last push 2026-10-23.
A server side alternative implementation of socket.io in PHP based on workerman.
Measured star growth
- in 24h
- 0
- in 7 days
- Collecting history
- in 15 days
- Collecting history
- in 1 month
- Collecting history
Net star changes over overlapping periods, not daily totals. Missing measurements are left blank. Stars measure attention, not software quality.
README.md
Originalphpsocket.io
A server-side PHP implementation of socket.io based on Workerman.
Notice: Only supports socket.io client >= v1.3.0 and <= v2.x (verified end-to-end against
[email protected], the last 2.x release, over both polling and websocket transports). **socket.io v3 and v4 are not supported.** Requires PHP >= 7.4 and Workerman >= 4.0 < 5.0. Workerman 5.x is not supported. For the full server API, see socket.io/docs/v2/server-api. Upgrading from v2.x? See UPGRADING.md for what changed in v3.0.0.
Table of contents
Install
v3.0.0 is in pre-release. This README documents it, and Composer only installs it when asked:
composer require workerman/phpsocket.io:^3.0@beta
Coming from v2.x, read UPGRADING.md first. Please report problems in the issues. For the current stable release (v2.x):
composer require workerman/phpsocket.io
Examples
Simple chat
start.php
<?php
use Workerman\Worker;
use PHPSocketIO\SocketIO;
require_once __DIR__ . '/vendor/autoload.php';
// Listen on port 2026 for socket.io clients
$io = new SocketIO(2026);
$io->on('connection', function ($socket) use ($io) {
$socket->on('chat message', function ($msg) use ($io) {
$io->emit('chat message', $msg);
});
});
Worker::runAll();
Another chat demo
Full source: examples/chat/start_io.php
<?php
use Workerman\Worker;
use PHPSocketIO\SocketIO;
require_once __DIR__ . '/vendor/autoload.php';
$io = new SocketIO(2026);
$io->on('connection', function ($socket) {
$socket->addedUser = false;
// When the client emits 'new message', this listens and executes
$socket->on('new message', function ($data) use ($socket) {
$socket->broadcast->emit('new message', [
'username' => $socket->username,
'message' => $data,
]);
});
// When the client emits 'add user', this listens and executes
$socket->on('add user', function ($username) use ($socket) {
// Note: global variables are used here for simplicity (demo only)
global $usernames, $numUsers;
$socket->username = $username;
$usernames[$username] = $username;
++$numUsers;
$socket->addedUser = true;
$socket->emit('login', ['numUsers' => $numUsers]);
$socket->broadcast->emit('user joined', [
'username' => $socket->username,
'numUsers' => $numUsers,
]);
});
// When the client emits 'typing', broadcast it to others
$socket->on('typing', function () use ($socket) {
$socket->broadcast->emit('typing', ['username' => $socket->username]);
});
// When the client emits 'stop typing', broadcast it to others
$socket->on('stop typing', function () use ($socket) {
$socket->broadcast->emit('stop typing', ['username' => $socket->username]);
});
// When the user disconnects
$socket->on('disconnect', function () use ($socket) {
global $usernames, $numUsers;
if ($socket->addedUser) {
unset($usernames[$socket->username]);
--$numUsers;
$socket->broadcast->emit('user left', [
'username' => $socket->username,
'numUsers' => $numUsers,
]);
}
});
});
Worker::runAll();
Enable SSL (HTTPS)
Requires phpsocket.io >= 1.1.1 and workerman >= 3.3.7
start.php
<?php
use Workerman\Worker;
use PHPSocketIO\SocketIO;
require_once __DIR__ . '/vendor/autoload.php';
$context = [
'ssl' => [
'local_cert' => '/your/path/of/server.pem',
'local_pk' => '/your/path/of/server.key',
'verify_peer' => false,
],
];
$io = new SocketIO(2026, $context);
$io->on('connection', function ($socket) {
echo "New connection: {$socket->id}\n";
});
Worker::runAll();
Acknowledgement callback
<?php
use Workerman\Worker;
use PHPSocketIO\SocketIO;
require_once __DIR__ . '/vendor/autoload.php';
$io = new SocketIO(2026);
$io->on('connection', function ($socket) {
$socket->on('message with ack', function ($data, $callback) {
if ($callback && is_callable($callback)) {
$callback(0);
}
});
});
Worker::runAll();
Multiple processes
A single process keeps every socket in its own memory, so emit(), to($room)
and to($sid) only reach sockets in that process. To run several worker
processes, or several servers, use ChannelAdapter: it relays broadcasts
through a workerman/channel server.
<?php
use Workerman\Worker;
use PHPSocketIO\SocketIO;
use PHPSocketIO\ChannelAdapter;
require_once __DIR__ . '/vendor/autoload.php';
// Pub/sub hub the worker processes use to reach each other's sockets.
$channel = new Channel\Server('127.0.0.1', 2206);
$io = new SocketIO(2026);
$io->worker->count = 4;
// ChannelAdapter connects to the channel server, which needs the event loop:
// set it in workerStart, not through the constructor's 'adapter' option.
$io->on('workerStart', function () use ($io) {
$io->adapter(ChannelAdapter::class);
});
$io->on('connection', function ($socket) {
$socket->on('chat message', function ($msg) use ($socket) {
$socket->broadcast->emit('chat message', $msg);
});
});
Worker::runAll();
For a channel server on another host, set
ChannelAdapter::$ipandChannelAdapter::$portbeforeWorker::runAll(), and runChannel\Serverthere instead.Clients must connect with the WebSocket transport only when several processes share a port, or several servers sit behind a load balancer without sticky sessions: HTTP long-polling requests from one client can land on different processes, and the handshake fails.
const socket = io('http://localhost:2026', { transports: ['websocket'] });
Run the examples
Chat (examples/chat)
A full chat room demo -- online user list, typing indicators, message timestamps, and color-coded server-side logging.
docker compose up --build # or: docker compose up --build phpsocketio
Then open http://localhost:2027 (Socket.IO on port 2026).
Without Docker:
cd examples/chat
php start.php start # debug mode
php start.php start -d # daemon mode
php start.php stop # stop
php start.php status # status
Rooms (examples/rooms)
A minimal demo of socket->join()/leave()/to(room)->emit() -- join a room, message
everyone else in it, leave, and watch the member list update live.
docker compose up --build rooms
Then open http://localhost:2031 (Socket.IO on port 2030) in two
browser tabs.
Without Docker:
cd examples/rooms
php start.php start
Acknowledgements (examples/ack)
Both directions of emit(event, data, callback) -- client asking the server to ack, and
the server asking a specific client to ack back.
docker compose up --build ack
Then open http://localhost:2033 (Socket.IO on port 2032).
Without Docker:
cd examples/ack
php start.php start
Namespaces (examples/namespaces)
Two independent channels (/public, /admin) on the same server via io->of() -- messages
in one never reach clients connected to the other.
docker compose up --build namespaces
Then open http://localhost:2035 (Socket.IO on port 2034).
Without Docker:
cd examples/namespaces
php start.php start
Development
This project uses GitHub Actions to run on every pull request and push to master:
- PHP_CodeSniffer, ensuring the codebase follows the coding standard defined in
phpcs.xml. - The PHPUnit test suite, across PHP 7.4 through 8.5.
To run locally:
# Without Docker
composer install
composer lint # vendor/bin/phpcs src/
composer test # vendor/bin/phpunit
# With Docker
docker compose --profile tools run --rm phpcs
docker compose --profile tools run --rm phpunit
Contributing
Contributions are welcome! See CONTRIBUTING.md for how to set up the project, run checks locally, and submit a pull request.
License
Explore related projects
codecrafters-io/build-your-own-x
Master programming by recreating your favorite technologies from scratch.
560,805 starspublic-apis/public-apis
A collective list of free APIs
497,039 starsmorluto/rea
Reverse engineer anything with agents, from app behavior down to native binaries.
441,222 starsopenclaw/openclaw
The AI that really does things. Any OS. Any Platform. The lobster way. 🦞
394,149 stars