assertTrue(MockSocket::isEmpty()); MockSocket::initialize('server.accept', $this); $server->accept(); $server->send('Connect'); $this->assertEquals(8000, $server->getPort()); $this->assertEquals('/my/mock/path', $server->getPath()); $this->assertTrue($server->isConnected()); $this->assertEquals(4096, $server->getFragmentSize()); $this->assertNull($server->getCloseStatus()); $this->assertEquals([ 'GET /my/mock/path HTTP/1.1', 'host: localhost:8000', 'user-agent: websocket-client-php', 'connection: Upgrade', 'upgrade: websocket', 'sec-websocket-key: cktLWXhUdDQ2OXF0ZCFqOQ==', 'sec-websocket-version: 13', '', '', ], $server->getRequest()); $this->assertEquals('websocket-client-php', $server->getHeader('USER-AGENT')); $this->assertNull($server->getHeader('no such header')); $this->assertTrue(MockSocket::isEmpty()); MockSocket::initialize('send-receive', $this); $server->send('Sending a message'); $message = $server->receive(); $this->assertEquals('Receiving a message', $message); $this->assertTrue(MockSocket::isEmpty()); $this->assertNull($server->getCloseStatus()); $this->assertEquals('text', $server->getLastOpcode()); MockSocket::initialize('server.close', $this); $server->close(); $this->assertFalse($server->isConnected()); $this->assertEquals(1000, $server->getCloseStatus()); $this->assertEquals('close', $server->getLastOpcode()); $this->assertTrue(MockSocket::isEmpty()); $server->close(); // Already closed } public function testDestruct(): void { MockSocket::initialize('server.construct', $this); $server = new Server(); MockSocket::initialize('server.accept-destruct', $this); $server->accept(); $message = $server->receive(); } public function testServerWithTimeout(): void { MockSocket::initialize('server.construct', $this); $server = new Server(['timeout' => 300]); $this->assertTrue(MockSocket::isEmpty()); MockSocket::initialize('server.accept-timeout', $this); $server->accept(); $server->send('Connect'); $this->assertTrue(MockSocket::isEmpty()); } public function testPayload128(): void { MockSocket::initialize('server.construct', $this); $server = new Server(); $this->assertTrue(MockSocket::isEmpty()); MockSocket::initialize('server.accept', $this); $server->accept(); $server->send('Connect'); $this->assertTrue($server->isConnected()); $this->assertTrue(MockSocket::isEmpty()); $payload = file_get_contents(__DIR__ . '/mock/payload.128.txt'); MockSocket::initialize('send-receive-128', $this); $server->send($payload, 'text', false); $message = $server->receive(); $this->assertEquals($payload, $message); $this->assertTrue(MockSocket::isEmpty()); } public function testPayload65536(): void { MockSocket::initialize('server.construct', $this); $server = new Server(); $this->assertTrue(MockSocket::isEmpty()); MockSocket::initialize('server.accept', $this); $server->accept(); $server->send('Connect'); $this->assertTrue($server->isConnected()); $this->assertTrue(MockSocket::isEmpty()); $payload = file_get_contents(__DIR__ . '/mock/payload.65536.txt'); $server->setFragmentSize(65540); MockSocket::initialize('send-receive-65536', $this); $server->send($payload, 'text', false); $message = $server->receive(); $this->assertEquals($payload, $message); $this->assertTrue(MockSocket::isEmpty()); } public function testMultiFragment(): void { MockSocket::initialize('server.construct', $this); $server = new Server(); $this->assertTrue(MockSocket::isEmpty()); MockSocket::initialize('server.accept', $this); $server->accept(); $server->send('Connect'); $this->assertTrue($server->isConnected()); $this->assertTrue(MockSocket::isEmpty()); MockSocket::initialize('send-receive-multi-fragment', $this); $server->setFragmentSize(8); $server->send('Multi fragment test'); $message = $server->receive(); $this->assertEquals('Multi fragment test', $message); $this->assertTrue(MockSocket::isEmpty()); } public function testPingPong(): void { MockSocket::initialize('server.construct', $this); $server = new Server(); $this->assertTrue(MockSocket::isEmpty()); MockSocket::initialize('server.accept', $this); $server->accept(); $server->send('Connect'); $this->assertTrue($server->isConnected()); $this->assertTrue(MockSocket::isEmpty()); MockSocket::initialize('ping-pong', $this); $server->send('Server ping', 'ping'); $server->send('', 'ping'); $message = $server->receive(); $this->assertEquals('Receiving a message', $message); $this->assertEquals('text', $server->getLastOpcode()); $this->assertTrue(MockSocket::isEmpty()); } public function testRemoteClose(): void { MockSocket::initialize('server.construct', $this); $server = new Server(); $this->assertTrue(MockSocket::isEmpty()); MockSocket::initialize('server.accept', $this); $server->accept(); $server->send('Connect'); $this->assertTrue($server->isConnected()); $this->assertTrue(MockSocket::isEmpty()); MockSocket::initialize('close-remote', $this); $message = $server->receive(); $this->assertEquals('', $message); $this->assertTrue(MockSocket::isEmpty()); $this->assertFalse($server->isConnected()); $this->assertEquals(17260, $server->getCloseStatus()); $this->assertEquals('close', $server->getLastOpcode()); } public function testSetTimeout(): void { MockSocket::initialize('server.construct', $this); $server = new Server(); $this->assertTrue(MockSocket::isEmpty()); MockSocket::initialize('server.accept', $this); $server->accept(); $server->send('Connect'); $this->assertTrue($server->isConnected()); $this->assertTrue(MockSocket::isEmpty()); MockSocket::initialize('config-timeout', $this); $server->setTimeout(300); $this->assertTrue($server->isConnected()); $this->assertTrue(MockSocket::isEmpty()); } public function testFailedSocketServer(): void { MockSocket::initialize('server.construct-failed-socket-server', $this); $this->expectException('WebSocket\ConnectionException'); $this->expectExceptionCode(0); $this->expectExceptionMessage('Could not open listening socket:'); $server = new Server(['port' => 9999]); } public function testFailedConnect(): void { MockSocket::initialize('server.construct', $this); $server = new Server(); MockSocket::initialize('server.accept-failed-connect', $this); $server->accept(); $this->expectException('WebSocket\ConnectionException'); $this->expectExceptionCode(0); $this->expectExceptionMessage('Server failed to connect'); $server->send('Connect'); } public function testFailedConnectTimeout(): void { MockSocket::initialize('server.construct', $this); $server = new Server(['timeout' => 300]); MockSocket::initialize('server.accept-failed-connect', $this); $server->accept(); $this->expectException('WebSocket\ConnectionException'); $this->expectExceptionCode(0); $this->expectExceptionMessage('Server failed to connect'); $server->send('Connect'); } public function testFailedHttp(): void { MockSocket::initialize('server.construct', $this); $server = new Server(); MockSocket::initialize('server.accept-failed-http', $this); $server->accept(); $this->expectException('WebSocket\ConnectionException'); $this->expectExceptionCode(0); $this->expectExceptionMessage('No GET in request'); $server->send('Connect'); } public function testFailedWsKey(): void { MockSocket::initialize('server.construct', $this); $server = new Server(); MockSocket::initialize('server.accept-failed-ws-key', $this); $server->accept(); $this->expectException('WebSocket\ConnectionException'); $this->expectExceptionCode(0); $this->expectExceptionMessage('Client had no Key in upgrade request'); $server->send('Connect'); } public function testSendBadOpcode(): void { MockSocket::initialize('server.construct', $this); $server = new Server(); MockSocket::initialize('server.accept', $this); $server->accept(); $server->send('Connect'); $this->expectException('WebSocket\BadOpcodeException'); $this->expectExceptionCode(0); $this->expectExceptionMessage('Bad opcode \'bad\'. Try \'text\' or \'binary\'.'); $server->send('Bad Opcode', 'bad'); } public function testRecieveBadOpcode(): void { MockSocket::initialize('server.construct', $this); $server = new Server(); MockSocket::initialize('server.accept', $this); $server->accept(); $server->send('Connect'); MockSocket::initialize('receive-bad-opcode', $this); $this->expectException('WebSocket\ConnectionException'); $this->expectExceptionCode(1026); $this->expectExceptionMessage('Bad opcode in websocket frame: 12'); $message = $server->receive(); } public function testBrokenWrite(): void { MockSocket::initialize('server.construct', $this); $server = new Server(); MockSocket::initialize('server.accept', $this); $server->accept(); $server->send('Connect'); MockSocket::initialize('send-broken-write', $this); $this->expectException('WebSocket\ConnectionException'); $this->expectExceptionCode(1025); $this->expectExceptionMessage('Could only write 18 out of 22 bytes.'); $server->send('Failing to write'); } public function testFailedWrite(): void { MockSocket::initialize('server.construct', $this); $server = new Server(); MockSocket::initialize('server.accept', $this); $server->accept(); $server->send('Connect'); MockSocket::initialize('send-failed-write', $this); $this->expectException('WebSocket\TimeoutException'); $this->expectExceptionCode(1024); $this->expectExceptionMessage('Failed to write 22 bytes.'); $server->send('Failing to write'); } public function testBrokenRead(): void { MockSocket::initialize('server.construct', $this); $server = new Server(); MockSocket::initialize('server.accept', $this); $server->accept(); $server->send('Connect'); MockSocket::initialize('receive-broken-read', $this); $this->expectException('WebSocket\ConnectionException'); $this->expectExceptionCode(1025); $this->expectExceptionMessage('Broken frame, read 0 of stated 2 bytes.'); $server->receive(); } public function testEmptyRead(): void { MockSocket::initialize('server.construct', $this); $server = new Server(); MockSocket::initialize('server.accept', $this); $server->accept(); $server->send('Connect'); MockSocket::initialize('receive-empty-read', $this); $this->expectException('WebSocket\TimeoutException'); $this->expectExceptionCode(1024); $this->expectExceptionMessage('Empty read; connection dead?'); $server->receive(); } }