Skip to content

Commit

Permalink
refatcing session connection stroage for ws,tcp
Browse files Browse the repository at this point in the history
  • Loading branch information
inhere committed Dec 19, 2019
1 parent 0cf1062 commit 5a52586
Show file tree
Hide file tree
Showing 11 changed files with 284 additions and 266 deletions.
172 changes: 172 additions & 0 deletions src/framework/src/Concern/AbstractSessionManager.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
<?php declare(strict_types=1);

namespace Swoft\Concern;

use Swoft\Contract\SessionInterface;
use Swoft\Contract\SessionStorageInterface;
use Swoft\Exception\SessionException;
use Swoft\Session\ArrayStorage;
use Swoft\Session\Session;
use function gethostname;

/**
* Class AbstractSessionManager session connection manager
*
* @since 2.0.8
*/
abstract class AbstractSessionManager
{
/**
* The session storage handler
*
* @var SessionStorageInterface
*/
private $storage;

/**
* @var string
*/
protected $prefix = 'ss';

/**
* Bean init
*/
public function init(): void
{
// Ensure the this->storage property is not empty.
if (!$this->storage) {
$this->storage = new ArrayStorage();
}
}

/**
* @param string $sessionId
*
* @return string eg: "wsMyHost:23"
*/
public function genKey(string $sessionId): string
{
$hostname = gethostname();

return $this->prefix . $hostname . ':' . $sessionId;
}

/**
* @param string $sessionId
*
* @return bool
*/
public function has(string $sessionId): bool
{
if (Session::has($sessionId)) {
return true;
}

$sessKey = $this->genKey($sessionId);

return $this->storage->exists($sessKey);
}

/**
* @param string $sessionId The session Id. eg: swoole.fd, http session id
* @param SessionInterface $session
*
* @return bool
*/
public function set(string $sessionId, SessionInterface $session): bool
{
// Cache to Session::class
Session::set($sessionId, $session);

$sessKey = $this->genKey($sessionId);

return $this->storage->write($sessKey, $session->toString());
}

/**
* @param string $sessionId The session Id. eg: swoole.fd, http session id
*
* @return SessionInterface|null
*/
public function get(string $sessionId): ?SessionInterface
{
// Read from caches
if ($sess = Session::get($sessionId)) {
return $sess;
}

// Read from storage
$sessionKey = $this->genKey($sessionId);
$sessionData = $this->storage->read($sessionKey);

if ($sessionData) {
$sess = $this->restoreSession($sessionData);

// Cache to memory
Session::set($sessionId, $sess);
return $sess;
}

return null;
}

/**
* @param string $sessionData
*
* @return SessionInterface
*/
abstract protected function restoreSession(string $sessionData): SessionInterface;

/**
* @param string $sessionId
*
* @return SessionInterface
*/
public function mustGet(string $sessionId): SessionInterface
{
if ($session = $this->get($sessionId)) {
return $session;
}

// throw new UnexpectedValueException('The session is not exists! sessionId is ' . $sessionId);
throw new SessionException('session information has been lost of the SID: ' . $sessionId);
}

/**
* @param string $sessionId
*
* @return bool
*/
public function destroy(string $sessionId): bool
{
Session::destroy($sessionId);

$sessKey = $this->genKey($sessionId);

return $this->storage->destroy($sessKey);
}

/**
* @return bool
*/
public function clear(): bool
{
return $this->storage->clear();
}

/**
* @return SessionStorageInterface
*/
public function getStorage(): SessionStorageInterface
{
return $this->storage;
}

/**
* @param SessionStorageInterface $storage
*/
public function setStorage(SessionStorageInterface $storage): void
{
$this->storage = $storage;
}
}
2 changes: 2 additions & 0 deletions src/framework/src/Session/ArrayStorage.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
/**
* Class ArrayStorageHandler
*
* NOTICE: only can use for test run, storage data will lost of on worker reload.
*
* @since 2.0.8
*/
class ArrayStorage implements SessionStorageInterface
Expand Down
82 changes: 41 additions & 41 deletions src/framework/src/Session/Session.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,18 @@

namespace Swoft\Session;

use Swoft;
use Swoft\Co;
use Swoft\Contract\SessionInterface;
use Swoft\Exception\SessionException;
use Swoft\WebSocket\Server\Connection;

/**
* Class Session - Global long connection session manager(use for ws,tcp)
*
* @since 2.0
*/
final class Session
class Session
{
// The global session manager and storage bean name
public const ManagerBean = 'gSessionManager';
public const StorageBean = 'gSessionStorage';

/**
* The map for coroutineID to SessionID
*
Expand All @@ -26,12 +22,23 @@ final class Session
private static $idMap = [];

/**
* @return SessionManager
* Activity ws/tcp session connection list.
*
* NOTICE: storage data will lost of on worker reload.
*
* @var SessionInterface[]
*
* @example
* [
* // Such as webSocket connection
* 'fd' => SessionInterface,
* 'fd2' => SessionInterface,
* 'fd3' => SessionInterface,
* // Such as http session
* 'sess id' => SessionInterface,
* ]
*/
public static function getManager(): SessionManager
{
return Swoft::getBean(self::ManagerBean);
}
private static $sessions = [];

/*****************************************************************************
* SID and CID relationship manage
Expand Down Expand Up @@ -89,21 +96,20 @@ public static function getBoundedSid(): string
*/
public static function has(string $sid): bool
{
return self::getManager()->has($sid);
return isset(self::$sessions[$sid]);
}

/**
* Get session by FD
*
* @param string $sid If not specified, return the current corresponding session
*
* @return SessionInterface|Connection
*/
public static function get(string $sid = ''): ?SessionInterface
{
$sid = $sid ?: self::getBoundedSid();

return self::getManager()->get($sid);
return self::$sessions[$sid] ?? null;
}

/**
Expand All @@ -114,23 +120,28 @@ public static function get(string $sid = ''): ?SessionInterface
public static function current(): SessionInterface
{
$sid = self::getBoundedSid();
if (isset(self::$sessions[$sid])) {
return self::$sessions[$sid];
}

return self::getManager()->mustGet($sid);
throw new SessionException('session information has been lost of the SID: ' . $sid);
}

/**
* Get connection by FD. if not found will throw exception.
* NOTICE: recommend use Session::current() instead of the method.
*
* @param string $sid
*
* @return SessionInterface|Connection
*/
public static function mustGet(string $sid = ''): SessionInterface
{
$sid = $sid ?: self::getBoundedSid();

return self::getManager()->mustGet($sid);
if (isset(self::$sessions[$sid])) {
return self::$sessions[$sid];
}

throw new SessionException('session information has been lost of the SID: ' . $sid);
}

/**
Expand All @@ -141,43 +152,34 @@ public static function mustGet(string $sid = ''): SessionInterface
*/
public static function set(string $sid, SessionInterface $session): void
{
// self::$sessions[$sid] = $session;
self::getManager()->set($sid, $session);
self::$sessions[$sid] = $session;

// Bind cid => sid(fd)
self::bindCo($sid);
}

/**
* Destroy session by sessionId
* Destroy session
*
* @param string $sid If empty, destroy current CID relationship session
*
* @return bool
*/
public static function destroy(string $sid): bool
public static function destroy(string $sid = ''): void
{
return self::getManager()->destroy($sid);
$sid = $sid ?: self::getBoundedSid();

if (isset(self::$sessions[$sid])) {
// Clear self data.
self::$sessions[$sid]->clear();
unset(self::$sessions[$sid]);
}
}

/**
* Clear all
*/
public static function clear(): void
{
self::$idMap = [];

self::getManager()->clear();
}

/**
* Clear all caches
*/
public static function clearCaches(): void
{
self::$idMap = [];

self::getManager()->clearCaches();
self::$idMap = self::$sessions = [];
}

/**
Expand All @@ -189,12 +191,10 @@ public static function getIdMap(): array
}

/**
* Only get all sessions in current worker memory.
*
* @return SessionInterface[]
*/
public static function getSessions(): array
{
return self::getManager()->getCaches();
return self::$sessions;
}
}
Loading

0 comments on commit 5a52586

Please sign in to comment.