Skip to content

Commit

Permalink
Merge branch 'recursion'
Browse files Browse the repository at this point in the history
  • Loading branch information
cboden committed Jan 1, 2017
2 parents b3694c6 + 1d0374f commit 56aecde
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 6 deletions.
16 changes: 10 additions & 6 deletions src/Messaging/MessageBuffer.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,17 +55,23 @@ function __construct(
$this->onControl = $onControl ?: function() {};
}

public function onData($data) {
while (strlen($data) > 0) {
$data = $this->processData($data);
}
}

/**
* @param string $data
* @return null
*/
public function onData($data) {
private function processData($data) {
$this->messageBuffer ?: $this->messageBuffer = $this->newMessage();
$this->frameBuffer ?: $this->frameBuffer = $this->newFrame();

$this->frameBuffer->addBuffer($data);
if (!$this->frameBuffer->isCoalesced()) {
return;
return '';
}

$onMessage = $this->onMessage;
Expand All @@ -82,7 +88,7 @@ public function onData($data) {
$onControl($this->frameBuffer);

if (Frame::OP_CLOSE === $opcode) {
return;
return '';
}
} else {
$this->messageBuffer->addFrame($this->frameBuffer);
Expand All @@ -101,9 +107,7 @@ public function onData($data) {
$this->messageBuffer = null;
}

if (strlen($overflow) > 0) {
$this->onData($overflow); // PHP doesn't do tail recursion :(
}
return $overflow;
}

/**
Expand Down
39 changes: 39 additions & 0 deletions tests/unit/Messaging/MessageBufferTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php

namespace Ratchet\RFC6455\Test\Unit\Messaging;

use Ratchet\RFC6455\Messaging\CloseFrameChecker;
use Ratchet\RFC6455\Messaging\Frame;
use Ratchet\RFC6455\Messaging\Message;
use Ratchet\RFC6455\Messaging\MessageBuffer;

class MessageBufferTest extends \PHPUnit_Framework_TestCase
{
/**
* This is to test that MessageBuffer can handle a large receive
* buffer with many many frames without blowing the stack (pre-v0.4 issue)
*/
public function testProcessingLotsOfFramesInASingleChunk() {
$frame = new Frame('a', true, Frame::OP_TEXT);

$frameRaw = $frame->getContents();

$data = str_repeat($frameRaw, 1000);

$messageCount = 0;

$messageBuffer = new MessageBuffer(
new CloseFrameChecker(),
function (Message $message) use (&$messageCount) {
$messageCount++;
$this->assertEquals('a', $message->getPayload());
},
null,
false
);

$messageBuffer->onData($data);

$this->assertEquals(1000, $messageCount);
}
}

0 comments on commit 56aecde

Please sign in to comment.