Skip to content

Instantly share code, notes, and snippets.

@mbonneau
Created March 31, 2017 16:28
Show Gist options
  • Save mbonneau/821096940a0f32091f6475c404697193 to your computer and use it in GitHub Desktop.
Save mbonneau/821096940a0f32091f6475c404697193 to your computer and use it in GitHub Desktop.
<?php
// This is an example WebSocket echo server using
// react/http (https://github.com/mbonneau/http/tree/969b2e46726868620d6238720694e59a34354250)
// with ratchet/rfc6455 (https://github.com/mbonneau/RFC6455/tree/a1f7487ff81bd914c69c425984803a9f2eaf51a1)
use Psr\Http\Message\RequestInterface;
use Ratchet\RFC6455\Handshake\RequestVerifier;
use Ratchet\RFC6455\Handshake\ServerNegotiator;
use Ratchet\RFC6455\Messaging\CloseFrameChecker;
use Ratchet\RFC6455\Messaging\Frame;
use Ratchet\RFC6455\Messaging\FrameInterface;
use Ratchet\RFC6455\Messaging\MessageBuffer;
use Ratchet\RFC6455\Messaging\MessageInterface;
use React\EventLoop\Factory;
use React\Http\Response;
use React\Socket\Server;
use React\Stream\ReadableStream;
require __DIR__ . '/vendor/autoload.php';
$loop = Factory::create();
$socket = new Server('tcp://127.0.0.1:6789/', $loop);
$negotiator = new ServerNegotiator(new RequestVerifier());
$http = new \React\Http\Server($socket, function (RequestInterface $request) use ($negotiator) {
$responseStream = new ReadableStream();
$response = $negotiator->handshake($request);
if ($response->getStatusCode() !== 101) {
return $response;
}
$body = $request->getBody();
$parser = new \Ratchet\RFC6455\Messaging\MessageBuffer(
new CloseFrameChecker(),
function (MessageInterface $message, MessageBuffer $messageBuffer) {
$messageBuffer->sendMessage($message->getPayload(), true, $message->isBinary());
},
function ($data) use ($responseStream) {
$responseStream->emit('data', [$data]);
},
function (FrameInterface $frame) use ($body, &$parser) {
switch ($frame->getOpCode()) {
case Frame::OP_CLOSE:
$body->end($frame->getContents());
break;
case Frame::OP_PING:
$body->write($parser->newFrame($frame->getPayload(), true, Frame::OP_PONG)->getContents());
break;
}
},
true
);
$body->on('data', [$parser, 'onData']);
$headers = [];
foreach ($response->getHeaders() as $headerName => $headerArray) {
$headers[$headerName] = $headerArray[0];
}
return new Response(
$response->getStatusCode(),
$headers,
$responseStream
);
});
$loop->run();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment