Мы пытались реализовать что-то для совместного использования ресурсов между пользовательскими потоками, используя TCP-соединения (без транспорта HTTP, поэтому нет SessionManager), но столкнулись с множеством проблем. В конце мы отказались от использования отдельных пользовательских потоков (установите LifeCycle := TDSLifeCycle.Server
) и создали наши собственные FResourcePool
и FUserList
(оба TThreadList
) в ServerContainerUnit . Это заняло всего 1 день, и это работает очень хорошо.
Вот упрощенная версия того, что мы сделали:
TResource = class
SomeResource: TSomeType;
UserCount: Integer;
LastSeen: TDateTime;
end;
Когда пользователь подключается, мы проверяем FResourcePool
на TResource
, в котором нуждается пользователь. Если он существует, мы увеличиваем свойство UserCount
ресурса. Когда пользователь закончил, мы уменьшаем свойство UserCount
и устанавливаем LastSeen
. У нас есть TTimer
, который срабатывает каждые 60 секунд, что освобождает любой ресурс с UserCount = 0
и LastSeen
, превышающими 60 секунд.
FUserList
очень похож. Если пользователь не был замечен в течение нескольких часов, мы предполагаем, что его соединение было разорвано (поскольку наше клиентское приложение выполняет автоматическое отключение, если пользователь простаивал в течение 90 минут), поэтому мы программно отключаем пользователя на стороне сервера. , что также уменьшает их использование каждого ресурса. Конечно, это означает, что нам пришлось самим создавать переменную сеанса (например, CreateGUID();
) и передавать ее клиенту при первом подключении. Клиент передает идентификатор сеанса обратно на сервер с каждым запросом, чтобы мы знали, какая запись FUserList
принадлежит им. Хотя это является недостатком , а не с использованием пользовательских потоков, им легко управлять.