yiisoft / session

A session service, PSR-15 session middleware, and a flash message service which helps use one-time messages.
https://www.yiiframework.com/
BSD 3-Clause "New" or "Revised" License
17 stars 8 forks source link

SessionMiddleware can not work on swoole #25

Open ChisWill opened 2 years ago

ChisWill commented 2 years ago

Hi guys,my application run with swoole, I found I can not use SessionMiddleware because Session will be overwrite by other request. Could we add Session into attribute of request, so we can use the way $request->getAttribute(SessionInterface::class) to get Session. We also can remain old usage by add a new property when application running different env.

Funding

Fund with Polar

samdark commented 2 years ago

Do you want to keep session in the worker context and not to destroy/recreate it on each request?

ChisWill commented 2 years ago

No, I will create a new PsrRequest instance on each request and this is not my point. I mean, when we use SessionInterface as a singleton and application is running on swoole,the code

if ($requestSessionId !== null && $this->session->getId() === null) {
    $this->session->setId($requestSessionId);
}

will modify session singleton and never execute setId() again when new request come. The result is every request has same session.

samdark commented 2 years ago

Wait, but $requestSessionId is obtained from request and you have different request object every time, don't you?

$requestSessionId = $this->getSessionIdFromRequest($request);
ChisWill commented 2 years ago

Yes, request is different. But, look at the if condition if ($requestSessionId !== null && $this->session->getId() === null) { $this->session had been modified and storage in memory, so after first request the $this->session->getId() is always not null. And at the last SessionMiddleware will commitSession(), it will modify current request session id to a same value which is $this->session->getId().

samdark commented 2 years ago

You're right. Any fix that comes in mind? I don't currently have Swoole environment set up :(

ChisWill commented 2 years ago

As I mentioned in the question, we should use the code $request->getAttribute(SessionInterface::class) to get Session. I think Session depends on request, it shouldn't be a singleton instance. However, this will affect the usage of the current user, so add a property to configure? It's up to you.

yiiliveext commented 2 years ago

You're right. Any fix that comes in mind? I don't currently have Swoole environment set up :(

Make sessionId nullable.

public function setId(?string $sessionId): void
{
    $this->sessionId = $sessionId;
}

And we should add resetter in the SessionInterface::class config for those who use yiisoft/di

ChisWill commented 2 years ago

I think it won't work well. In Swoole coroutine environment,suppose this situation: Even if there is only one process and the first request come and do sleep(), the process will also accept other request. At this time, the other request will modify the session, Until the sleeping request wakes up, his session had been changed. So I think every request should maintain its own session copy.

samdark commented 2 years ago
  1. Added resetter config.
  2. Updated https://github.com/yiisoft/docs/blob/master/guide/en/tutorial/using-yii-with-swoole.md

@ChisWill ping us if it doesn't help please.

ChisWill commented 2 years ago
  1. Added resetter config.
  2. Updated https://github.com/yiisoft/docs/blob/master/guide/en/tutorial/using-yii-with-swoole.md

@ChisWill ping us if it doesn't help please.

I refer to this article, but I found that in the same process session_id() always returns the same value when a new request comes. Why not use session_create_id() or other similar method?

alamagus commented 1 year ago

@ChisWill Php cli(on top of which swoole is run) has no idea about coroutines. So, at any given time there is 0 or 1 session in the process. And when you call session_* functions 'simultaneously' from different coroutines, you still operate on 1(or 0) session src Might be wrong tho :thinking: