TServerSocket и TService

oklalex
Дата: 01.10.2019 06:15:26
Доброго времени, уважаемые форумчане!
Прошу помощи в следующем. Имеем "отладочное" приложение, которое содержит TServerSocket, работающий в неблокирующем режиме (stNonBlocking) и принимающий данные от кучи разных устройств/локальных клиентских программ и прочее. Все отлично работает, срабатывает событие OnClientRead(), выполняю обработку и, при необходимости, отправку данных при помощи SendText(). В случае, если данные были разбиты на части во время их передачи, OnClientRead() вызывается для каждой части по порядку и проблем тоже нет.

// при создании формы (службы)
FServerSocket := TServerSocket.Create(nil);
FServerSocket.OnClientError := OnError;
FServerSocket.OnClientRead := OnRead;
FServerSocket.OnClientDisconnect := OnDisconnect;

// при разрушении формы (службы)
for Index := 0 to FServerSocket.Socket.ActiveConnections - 1 do
  FServerSocket.Socket.Connections[Index].Close;
FServerSocket.Close;

Затем, все это дело я оформил как службу - штатный TService. И появилась такая проблема - все работает примерно в течение часа, затем перестает работать. Служба запущена всегда, остановок и исключений нет. Сделал свой собственный простой и примитивный лог - вижу, что после определенного количества подключений (около 100 активных sockets) перестает срабатывать событие OnClientRead(). То есть, клиент подключается, подключение проходит, но событие уже не срабатывает. При перезапуске службы, разумеется, все начинает работать, опять-таки до поры до времени. Если кто сталкивался с чем-то подобным, пуду премного признателен.
Может быть, дело в том, что нельзя использовать stNonBlocking внутри службы? Программа была идеально отлажена именно в этом режиме работы сервера.
DmSer
Дата: 01.10.2019 08:02:43
Сомнительно что-то. Если в режиме десктопа работает, то режиме службы должно. Может в каких-то ситуациях окна открываются, ShowMessage например?
oklalex
Дата: 01.10.2019 08:20:34
DmSer,
В том и дело, что нет никаких ShowMessage(), как будто бы есть какое-то ограничение на количество подключений (что-то типа ThreadCacheSize - но это для блокирующего режима и работы с потоками, а здесь все в главном потоке, ибо обработка очень быстрая).
Пока поставил в таймере такой "костыль" с интервалом на 1 час (3600000 мс).

try
  for Index := 0 to FServerSocket.Socket.ActiveConnections - 1 do
    FServerSocket.Socket.Connections[Index].Close;
  FServerSocket.Close;
finally
  if not FServerSocket.Active then
    FServerSocket.Open;
end;

Пока все это работает, но это не дело совсем, конечно...
DmSer
Дата: 01.10.2019 08:59:58
автор
а здесь все в главном потоке, ибо обработка очень быстрая.


Видимо у Вас где-то происходит зависание в основном потоке. Может дедлок? TService как-то взаимодейстует с TServerSocket?
oklalex
Дата: 01.10.2019 09:28:39
DmSer,
Теоретически не должно быть зависаний, ибо действующие подключения еще некоторое время работают, потом вообще умирает все. Кстати, вышеприведенный "костыль" не помог - все равно перестает срабатывать событие, я это вижу по своему кустарному логу и по факту того, что ответ SendText() перестает приходить через некоторое время (отправляю при помощи Packet Sender - эмулирую сообщение клиента). А каким образом TService может взаимодействовать с TServerSocket? Только запуск, остановка, обработка событий от TServerSocket.
Экземпляр TServerSocket создаю динамически в RunTime, ибо убрали их давно из палитры компонентов, так удобнее.
oklalex
Дата: 01.10.2019 09:32:14
DmSer,
Deadlock тоже не должно быть, ибо база работает на чтение, операция записи крайне редкая - и, думаю, это было бы хорошо видно еще в десктопном варианте, но там такого и близко не было
Zelius
Дата: 01.10.2019 09:37:53
oklalex,

имхо, либо в локе висит, тогда можно посмотреть каким-нибудь ProcessExplorer, так ли это
либо сокеты кончились, можно посмотреть тем же ProcessExplorer или netstat'ом
YuRock
Дата: 01.10.2019 09:56:40
Ставлю на исключение, которое что-то повесило.
Хотя, конечно, может быть и лок из-за какого-нибудь synchronize.
DmSer
Дата: 01.10.2019 10:05:27
YuRock
Ставлю на исключение, которое что-то повесило.


Кстати да, если в службе возникнет исключения, то, если оно не обработано в try..except, то будет открыто окно с ошибкой ShowMessage, которое в режиме службы никто не увидит.
oklalex
Дата: 01.10.2019 10:11:25
DmSer,
try... except все на месте, но все равно сейчас пытаюсь проверить на зависание/срабатывание Exception, может, где что упустил. В десктопе, правда, никаких исключений не выпадало, все обрабатывается.