Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2002.10.07;
Скачать: CL | DM;

Вниз

Проблема при дисконнекте   Найти похожие ветки 

 
VID ©   (2002-08-05 13:48) [0]

в общих чертах проблема в том что при событии onclientdisconnect я делаю след:
1. Отправляю всем клиентам, подключённым к серверу , к примеру S1(где, S1 - string)
2. Сразу же отправляю снова всем пользователям S2 - тоже String;

Приблизительно код выглядит так:
Procedure Server.OnClientDisconnect(..Socket:T...);
begin
SendPacketToAllClients(S1);
SendPacketToAllClient(S2);
end;

А вот и процедура SendPacket...

Procedure SendPacketToAllClients(Packet:String);
Var I:Integer;
begin
FOR I:=0 To Server.Socket.ActiveConnections - 1 do
Server.Socket.Connections [i].SendText(Packet);
end;

так вот при выполнении кода события onClientDisconnect , сервер виснет.
Причём, если прокомментировать одну из строк
(либо SendPacketToAllClients(S1), либо SendPacketToAllClient(S2)) то проблемы нет, сервак не виснет.


 
Digitman ©   (2002-08-05 14:04) [1]

Это - фрагмент хэлпа для события TServerWinSocket.OnClientDisconnect():

Occurs when one of the connections to a client socket is closed (!!!!!!!!!!!!!!!).


 
VID ©   (2002-08-05 14:17) [2]

дело в том, что в момент наступления OnClientDisconnect, Socket клиента ещё не закрыт... вот.
Но даже если переделать процедуру SendPacketToAllClients:
Procedure SendPacketToAllClients(Packet:String);
Var I:Integer;
begin
FOR I:=0 To Server.Socket.ActiveConnections - 1 do
IF SERVER.SOCKET.CONNECTIONS[i].CONNECTED THEN

Server.Socket.Connections [i].SendText(Packet);
end;

то всё равно проблема остаётся.

Да кстати, забыл сказать: если дисконнект происходит со стороны сервера (т.е. если сервер отключает клиента), то указанная проблема не возникает, даже если ни ода строка (в процедуре onClientDisconnect) не откомментирована. А вот если дисконнект со стороны клиента, то проблема есть


 
Digitman ©   (2002-08-05 14:37) [3]

И как же, позволь полюбопытствовать, ты что-то сможешь отослать клиенту по транспортному каналу, которого уже не существует ? Ведь в случае дисконнекта по инициативе клиента событие OnClientDisconnect() фиксирует именно факт уже произошедшего разрыва транспортного канала ! И в хэлпе об этом четко сказано - IS CLOSED.

разумеется, если дисконнект происходит по инициативе сервера, таким способом тебе еще что-то удастся (при асинхронном режиме) передать клиенту перед дисконнектом, но - не иначе !


 
VID ©   (2002-08-05 14:44) [4]

ну я так и знал.. спасибо :) кстати, server.servertype = nonblocking.
НУ тогда контрвопрос: а как же тогда быть ? Ведь мне надо после отключения клиента (неважно по чьей инициативе), послать ВСЕМ ОСТАВШИМСЯ сообщение типа "ушёл клиент "+Socket.RemoteAddress...
где же это сделать, что бы работало ?


 
Digitman ©   (2002-08-05 14:48) [5]

самый простой вариант :

если режим stThreadBlocking, попробуй просто заключить потенциально опасный send-метод в блок try..except


 
VID ©   (2002-08-05 14:57) [6]

нет нет... только не stThreadBlocking ... я использую stNonBlocking, и кстати, вот тебе вопрос:

№1 Почему же если откомментировать одну из строчек кода, приведённого в Server.OnClientDisconnect, то сервак не виснет, даже если дисконект был вызван со стороны клиента. Думается, что сервак просто "успевает" выполнить одну оставшуюся строчку кода, а если будет вторая то виснет.
И тут вопрос №2: Почему сервак вообще виснет? Зависание имеет след вид:
при событи onClientDisconnect у меня также есть ещё одна строчка (первее всех, но я её не указал, т.к. она не важна):
AddLog("Client "+Socket.RemoteAddress+" is disconnected");

Процедура AddLog:
Procedure Tform1.AddLog(Log:String);
begin
LogMemo.Lines.Add(Log);
end;

так вот зависание выглядит так:
сервер всё время добавляет лог :
Client 127.0.0.1 is disconnected
ВСЁ ВРЕМЯ. и не реагирует ни на что. Потом проихсодит переполнение стека и сервер выгружается из ОЗУ (Windows 2000).

И в продолжение темы:
№3 Как реализовать отправку всем оставшимся клиентам текстового сообщения, если Server.ServerType = stNonBlocking ?

Ps: прошу не задумываться над моим высказыванием "только не stThreadBlocking"... просто прими как факт ;)


 
Digitman ©   (2002-08-05 15:22) [7]

А как у тебя с обработкой события OnClientError () ? Игнорируешь ее ?


 
VID ©   (2002-08-05 15:52) [8]

Честно говоря, игнорировал... а что с ним делать ? Подскажи, пожалуйста....
Что необходимо реализовать при наступлении этого события ?


 
Digitman ©   (2002-08-05 15:56) [9]

1. Сбросить ErrorCode в 0.
2. Выполнить Socket.Close


 
VID ©   (2002-08-05 17:03) [10]

ВОПРОС ЗАКРЫТ. Большое спасибо, Digitman.



Страницы: 1 вся ветка

Текущий архив: 2002.10.07;
Скачать: CL | DM;

Наверх




Память: 0.49 MB
Время: 0.036 c
7-21291
Nalsur
2002-07-23 11:53
2002.10.07
Bios


8-21156
sergn
2002-06-07 19:00
2002.10.07
Конвертация bitmap в wfm c прозрачным фоном


1-21062
Shizoid
2002-09-27 15:57
2002.10.07
VCL source


1-21011
turusov
2002-09-25 15:24
2002.10.07
Object Pascal and Delphi


1-21131
Oleon
2002-09-24 15:56
2002.10.07
Привет! Где можно выставить DEFAULT_CHARSET, чтобы кирилица была.