Skip to content

Commit

Permalink
fix: ws server onOpen sometimes has a session loss error
Browse files Browse the repository at this point in the history
  • Loading branch information
inhere committed Aug 30, 2019
1 parent 93e9cf4 commit c2cd17a
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 10 deletions.
19 changes: 19 additions & 0 deletions src/http-server/src/Annotation/Mapping/RequestMapping.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,13 @@ class RequestMapping
*/
private $route = '';

/**
* Route name
*
* @var string
*/
private $name = '';

/**
* Routing supported HTTP method set
*
Expand Down Expand Up @@ -50,6 +57,10 @@ public function __construct(array $values)
$this->route = (string)$values['route'];
}

if (isset($values['name'])) {
$this->name = (string)$values['name'];
}

if (isset($values['method'])) {
$this->method = (array)$values['method'];
}
Expand Down Expand Up @@ -82,4 +93,12 @@ public function getParams(): array
{
return $this->params;
}

/**
* @return string
*/
public function getName(): string
{
return $this->name;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,11 @@ public function parse(int $type, $annotation): array
}

$routeInfo = [
'action' => $this->methodName,
'route' => $annotation->getRoute(),
'action' => $this->methodName,
'route' => $annotation->getRoute(),
'name' => $annotation->getName(),
'method' => $annotation->getMethod(),
'params' => $annotation->getParams(),
'params' => $annotation->getParams(),
];

// Add route info for controller action
Expand Down
20 changes: 13 additions & 7 deletions src/websocket-server/src/Swoole/HandshakeListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
use Swoft\Bean\Annotation\Mapping\Bean;
use Swoft\Bean\Annotation\Mapping\Inject;
use Swoft\Bean\BeanFactory;
use Swoft\Co;
use Swoft\Context\Context;
use Swoft\Http\Message\Request as Psr7Request;
use Swoft\Http\Message\Response as Psr7Response;
Expand All @@ -20,6 +19,7 @@
use Swoft\WebSocket\Server\WsDispatcher;
use Swoft\WebSocket\Server\WsErrorDispatcher;
use Swoft\WebSocket\Server\WsServerEvent;
use Swoole\Coroutine;
use Swoole\Http\Request;
use Swoole\Http\Response;
use Throwable;
Expand Down Expand Up @@ -100,17 +100,16 @@ public function onHandshake(Request $request, Response $response): bool
// Response handshake successfully
$meta = $conn->getMetadata();
$conn->setHandshake(true);

// Swoft::trigger(WsServerEvent::HANDSHAKE_SUCCESS, $fd, $request, $response);

// Response handshake
$psr7Res->quickSend();

$wsServer->log("Handshake: conn#{$fd} handshake successful! meta:", $meta, 'debug');
Swoft::trigger(WsServerEvent::HANDSHAKE_SUCCESS, $fd, $request, $response);

// Handshaking successful, Manually triggering the open event
Co::create(function () use ($psr7Req, $fd) {
// NOTICE:
// Cannot use \Swoft\Co::create().
// Because this will use the same top-level coroutine ID, if there is a first unbind, it may lead to session loss.
Coroutine::create(function () use ($psr7Req, $fd) {
$this->onOpen($psr7Req, $fd);
});
} catch (Throwable $e) {
Expand All @@ -119,7 +118,6 @@ public function onHandshake(Request $request, Response $response): bool
/** @var WsErrorDispatcher $errDispatcher */
$errDispatcher = BeanFactory::getSingleton(WsErrorDispatcher::class);

// Handle handshake error
$psr7Res = $errDispatcher->handshakeError($e, $psr7Res);
$psr7Res->quickSend();
} finally {
Expand Down Expand Up @@ -151,6 +149,8 @@ public function onOpen(Psr7Request $request, int $fd): void
server()->log("Open: conn#{$fd} has been opened", [], 'debug');

try {
Swoft::trigger(WsServerEvent::OPEN_BEFORE, $fd, $server, $request);

/** @var Connection $conn */
$conn = Session::mustGet();
$info = $conn->getModuleInfo();
Expand All @@ -173,6 +173,12 @@ public function onOpen(Psr7Request $request, int $fd): void
$errDispatcher = BeanFactory::getSingleton(WsErrorDispatcher::class);
$errDispatcher->openError($e, $request);
} finally {
// Defer
Swoft::trigger(SwoftEvent::COROUTINE_DEFER);

// Destroy
Swoft::trigger(SwoftEvent::COROUTINE_COMPLETE);

// Unbind cid => sid(fd)
Session::unbindCo();
}
Expand Down
12 changes: 12 additions & 0 deletions src/websocket-server/src/WsServerEvent.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,19 @@ final class WsServerEvent
*/
public const HANDSHAKE_ERROR = 'swoft.ws.server.handshake.error';

/**
* On websocket opened: before
*/
public const OPEN_BEFORE = 'swoft.ws.server.open.after';

/**
* On websocket opened: after
*/
public const OPEN_AFTER = 'swoft.ws.server.open.after';

/**
* On websocket opened: error
*/
public const OPEN_ERROR = 'swoft.ws.server.open.error';

/**
Expand Down

0 comments on commit c2cd17a

Please sign in to comment.