/** * Composes message to binary data to send it via stream * * @param SocketMessage $socketMessage * * @return string * */ public function compose(SocketMessage $socketMessage) { //Correlation + flag length + command length $messageLength = MessageConfiguration::HEADER_LENGTH; $doAuthorization = $socketMessage->getCredentials() ? true : false; $authorizationLength = 0; if ($doAuthorization) { $authorizationLength = 1 + strlen($socketMessage->getCredentials()->getUsername()) + 1 + strlen($socketMessage->getCredentials()->getPassword()); } $dataToSend = $socketMessage->getData(); if ($dataToSend) { $dataToSend = $dataToSend->serializeToString(); $messageLength += strlen($dataToSend); } $wholeMessageLength = $messageLength + $authorizationLength + MessageConfiguration::INT_32_LENGTH; $buffer = new Buffer($wholeMessageLength); $buffer->writeInt32LE($messageLength + $authorizationLength, 0); $buffer->writeInt8($socketMessage->getMessageType()->getType(), MessageConfiguration::MESSAGE_TYPE_OFFSET); $buffer->writeInt8($doAuthorization ? MessageConfiguration::FLAG_AUTHORIZATION : MessageConfiguration::FLAGS_NONE, MessageConfiguration::FLAG_OFFSET); $buffer->write(hex2bin($this->createCorrelationID($socketMessage->getCorrelationID())), MessageConfiguration::CORRELATION_ID_OFFSET); if ($doAuthorization) { $usernameLength = strlen($socketMessage->getCredentials()->getUsername()); $passwordLength = strlen($socketMessage->getCredentials()->getPassword()); $buffer->writeInt8($usernameLength, MessageConfiguration::DATA_OFFSET); $buffer->write($socketMessage->getCredentials()->getUsername(), MessageConfiguration::DATA_OFFSET + 1); $buffer->writeInt8($passwordLength, MessageConfiguration::DATA_OFFSET + 1 + $usernameLength); $buffer->write($socketMessage->getCredentials()->getPassword(), MessageConfiguration::DATA_OFFSET + 1 + $usernameLength + 1); } if ($dataToSend) { $buffer->write($dataToSend, MessageConfiguration::DATA_OFFSET + $authorizationLength); } return (string) $buffer; }
/** * Handles received data * * @param string $data * * @return SocketMessage|null */ public function handle($data) { try { if (!$data) { return null; } $socketMessages = array(); if (!is_null($this->currentMessage)) { $data = $this->currentMessage . $data; } do { $buffer = new Buffer($data); $dataLength = strlen($data); $messageLength = $buffer->readInt32LE(0) + MessageConfiguration::INT_32_LENGTH; if ($dataLength == $messageLength) { $socketMessages[] = $this->decomposeMessage($data); $this->currentMessage = null; } elseif ($dataLength > $messageLength) { $message = substr($data, 0, $messageLength); $socketMessages[] = $this->decomposeMessage($message); // reset data to next message $data = substr($data, $messageLength, $dataLength); $this->currentMessage = null; } else { $this->currentMessage .= $data; } } while ($dataLength > $messageLength); return $socketMessages; } catch (\Exception $e) { $this->logger->critical('Error during handling incoming message.' . ' Message Error: ' . $e->getMessage()); } }
/** * Handles received data * * @param string $data * * @return SocketMessage|null */ public function handle($data) { try { if (!$data) { return null; } if (is_null($this->currentMessage)) { $buffer = new Buffer($data); $dataLength = strlen($data); $messageLength = $buffer->readInt32LE(0) + MessageConfiguration::INT_32_LENGTH; if ($dataLength == $messageLength) { return $this->decomposeMessage($data); } if ($dataLength > $messageLength) { $this->currentMessage = substr($data, $messageLength + 1, $dataLength); return $this->decomposeMessage(substr($data, 0, $messageLength)); } $this->currentMessage = $this->currentMessage . $data; return null; } $buffer = new Buffer($this->currentMessage); $messageLength = $buffer->readInt32LE(0) + MessageConfiguration::INT_32_LENGTH; $mergedMessages = $this->currentMessage . $data; $dataLength = strlen($mergedMessages); if ($messageLength <= $dataLength) { $this->currentMessage = null; return $this->decomposeMessage($mergedMessages); } $this->currentMessage .= $data; return null; } catch (\Exception $e) { $this->logger->critical('Error during handling incoming message.' . ' Message Error: ' . $e->getMessage()); } }
protected function getRawData($channels, $message) { $buffer = new Buffer(4 + strlen($channels) + strlen($message)); $buffer->writeInt32BE(strlen($channels), 0); $buffer->write($channels, 4); $buffer->write($message, 4 + strlen($channels)); return (string) $buffer; }
/** * @throws NoSubscriptionException * * @return \TrafficCophp\Message\ServerMessage */ public function receive(AbstractServerMessage $message) { if (!$this->isRegistered()) { throw new NoSubscriptionException('Youre not subscribed on a channel!'); } $buffer = new Buffer($this->transport->receive(4)); $message->parse($this->transport->receive($buffer->readInt32BE(0))); return $message; }
/** * @test */ public function it_should_decompose_empty_message() { $wholeMessageLength = 0 + MessageConfiguration::INT_32_LENGTH + MessageConfiguration::HEADER_LENGTH; $buffer = new Buffer($wholeMessageLength); $buffer->writeInt32LE(18, 0); $buffer->writeInt8(MessageType::PING, MessageConfiguration::MESSAGE_TYPE_OFFSET); $buffer->writeInt8(MessageConfiguration::FLAGS_NONE, MessageConfiguration::FLAG_OFFSET); $buffer->write(hex2bin('12350000000000000000000000000000'), MessageConfiguration::CORRELATION_ID_OFFSET); PHPUnit_Framework_Assert::assertEquals('done', $this->messageDecomposer->decomposeMessage((string) $buffer)); }
public function parse($raw) { $buffer = new Buffer($raw); $channelLength = $buffer->readInt32BE(0); $channelList = $buffer->read(4, $channelLength); foreach (explode(',', $channelList) as $channelName) { $this->channels->addChannel(new Channel($channelName)); } $this->message = $buffer->read(4 + $channelLength, $buffer->length() - (4 + $channelLength)); $this->parsed = true; }
public function testReceive() { $transportMock = $this->getTransportMock(); $transportMock->expects($this->exactly(1))->method('send'); $channel = 'channel_one'; $message = 'message'; $buffer = new Buffer(4 + 11 + 7); $buffer->writeInt32BE(strlen($channel), 0); $buffer->write($channel, 4); $buffer->write($message, 4 + strlen($channel)); // Create a map of arguments to return values. $map = array(array(4, 26), array(22, (string) $buffer)); $transportMock->expects($this->exactly(2))->method('receive')->will($this->returnValueMap($map)); $subscriber = new Subscriber($transportMock); $messageMock = $this->getMockBuilder('TrafficCophp\\Message\\SubscribeMessage')->disableOriginalConstructor()->getMock(); $subscriber->subscribe($messageMock); $srvMessageMock = $this->getMockBuilder('TrafficCophp\\Message\\ServerMessage')->disableOriginalConstructor()->getMock(); $srvMessageMock->expects($this->exactly(1))->method('parse'); $subscriber->receive($srvMessageMock); }
public function testGetProtokollString() { $channel = new Channel('channel'); $message = 'php'; $buffer = new Buffer(4 + 1 + 4 + strlen($channel->getName()) + strlen($message)); $buffer->writeInt32BE($buffer->length() - 4, 0); $buffer->writeInt8(0x1, 4); $buffer->writeInt32BE(strlen($channel->getName()), 5); $buffer->write($channel->getName(), 9); $buffer->write($message, 9 + strlen($channel->getName())); $msg = new PublishMessage($channel, $message); $this->assertEquals((string) $buffer, $msg->getProtokollString()); }
/** * @test * @expectedException \RuntimeException */ public function it_should_compose_empty_message_without_auth() { $this->socketMessage = $this->socketMessage->reveal(); $binaryMessage = $this->messageComposer->compose($this->socketMessage); $buffer = new Buffer($binaryMessage); \PHPUnit_Framework_Assert::assertEquals(18, $buffer->readInt32LE(0)); \PHPUnit_Framework_TestCase::assertEquals(MessageType::HEARTBEAT_REQUEST, $buffer->readInt8(4)); \PHPUnit_Framework_TestCase::assertEquals(MessageConfiguration::FLAGS_NONE, $buffer->readInt8(5)); \PHPUnit_Framework_TestCase::assertEquals('12350000000000000000000000000000', bin2hex($buffer->read(6, 16))); //should throw exception out of range $buffer->read(22, 1); }
/** * Decomposes binary message, which comes from the stream * * @param string $message * * @return SocketMessage */ public function decomposeMessage($message) { $buffer = new Buffer($message); // Information about how long message is. To help it decode. Comes from the server // $messageLenght = (whole stream length) - (4 bytes for saved length). $messageLength = $buffer->readInt32LE(0); $messageType = new MessageType($buffer->readInt8(MessageConfiguration::MESSAGE_TYPE_OFFSET)); $flag = $buffer->readInt8(MessageConfiguration::FLAG_OFFSET); $correlationID = bin2hex($buffer->read(MessageConfiguration::CORRELATION_ID_OFFSET, MessageConfiguration::CORRELATION_ID_LENGTH)); $data = $buffer->read(MessageConfiguration::DATA_OFFSET, $messageLength - MessageConfiguration::HEADER_LENGTH); $communicable = $this->communicationFactory->create($messageType); return $communicable->handle($messageType, $correlationID, $data); }
public function testGetProtokollString() { $objectStoreage = new \SplObjectStorage(); $objectStoreage->attach($this->getChannelMock('channel_one')); $objectStoreage->attach($this->getChannelMock('channel_two')); $channels = $this->getMock('TrafficCophp\\Channel\\ChannelCollection'); $channels->expects($this->any())->method('getChannels')->will($this->returnValue($objectStoreage)); $msg = new SubscribeMessage($channels); $raw_channel_string = 'channel_one,channel_two'; $buf = new Buffer(4 + 1 + 4 + strlen($raw_channel_string)); $buf->writeInt32BE($buf->length() - 4, 0); $buf->writeInt8(0x2, 4); $buf->writeInt32BE(strlen($raw_channel_string), 5); $buf->write($raw_channel_string, 9); $this->assertSame((string) $buf, $msg->getProtokollString()); }
public function getLength() { return $this->buffer->length(); }
public function testWritingAndReadingOnTheSameBuffer() { $buffer = new Buffer(10); $int32be = 0.0; $string = 'hello!'; $buffer->writeInt32BE($int32be, 0); $buffer->write($string, 4); $this->assertSame($string, $buffer->read(4, 6)); $this->assertSame($int32be, $buffer->readInt32BE(0)); }