Форум: "Сети";
Текущий архив: 2002.12.02;
Скачать: [xml.tar.bz2];
ВнизОбсуждение статьи Найти похожие ветки
← →
megatrend (2002-09-25 18:22) [0]http://delphi.mastak.ru/articles/sockadv/index.html
Есть такой вопрос. Ниже приводится код сервера, в который вставлена моя отладочная печать. В коде есть некоторая ошибка, приводящая к тому, что когда на сервере есть N пользователей и к ним присоединяется N+1, то контактный лист посылается ВСЕМ N+1 раз.
Как бы это побороть? Ведь это расходы на трафик и процессорное
время.
procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var s: string;
i: Integer;
begin
{сохраняем в s присланную нам строку}
s := Socket.ReceiveText;
{Если кто-то прислал нам свое имя}
if Copy(s,1,2) = "#N" then begin
Delete(s,1,2);
{Добавляем его в юзер лист}
ListBox1.Items.Add(s);
say2log("Новый пользователь "+s);
{Записываем в s команду для посылки нового списка юзеров}
s := "#U";
for i := 0 to ListBox1.Items.Count-1 do
s := s+ListBox1.Items[i]+";";
{...и рассылаем этот список всем клиентам}
say2log("Всего соединений
"+inttostr(ServerSocket1.Socket.ActiveConnections));
for i := 0 to ServerSocket1.Socket.ActiveConnections-1 do
ServerSocket1.Socket.Connections[i].SendText(s);
Exit;
end;
...
Пример : В чат вошли друг за другом
Дима Белянцев, Олег Белянцев, Женя Белянцев.
Затем вышел Женя, Олег, Дима.
Вот итоговый лог на сервере.
25.09.2002 17:57:51 Сервер запущен
25.09.2002 17:59:21 Новый пользователь Дима Белянцев
25.09.2002 17:59:21 Всего соединений 1
25.09.2002 17:59:27 Новый пользователь Дима Белянцев
25.09.2002 17:59:27 Всего соединений 2
25.09.2002 17:59:27 Новый пользователь Олег Белянцев
25.09.2002 17:59:27 Всего соединений 2
25.09.2002 17:59:28 Новый пользователь Дима Белянцев
25.09.2002 17:59:28 Всего соединений 3
25.09.2002 17:59:28 Новый пользователь Олег Белянцев
25.09.2002 17:59:28 Всего соединений 3
25.09.2002 17:59:28 Новый пользователь Женя Белянцев
25.09.2002 17:59:28 Всего соединений 3
25.09.2002 17:59:36 Новый пользователь Дима Белянцев
25.09.2002 17:59:36 Всего соединений 2
25.09.2002 17:59:36 Новый пользователь Олег Белянцев
25.09.2002 17:59:36 Всего соединений 2
25.09.2002 17:59:38 Новый пользователь Дима Белянцев
25.09.2002 17:59:38 Всего соединений 1
← →
megatrend (2002-09-26 10:04) [1]Еще один глюк такой технологии написании чата : клиенту при дисконнекте одного из других клиентов (сервер начинает построение списка контактов с нуля) несколько раз передается все возрастающий список контактов (начиная с первого приславшего имя серверу), из-за чего некоторые списки контактов от сервера сливаются в один.
← →
megatrend (2002-09-27 09:25) [2]?
← →
Anatoly Podgoretsky (2002-09-27 09:33) [3]Так надо технологию менять, новому клиенту посылать весь список, а другим только дельту
← →
VID (2002-09-27 10:01) [4]>некоторые списки контактов от сервера сливаются в один
Нормальное явление. на приёмнике пакета, надо просто реализовать "расклеивание" таких пакетов. Вообще эта тема обсуждалась на этой конфе, посмотри на 2,3,4 страницах
А вообще, тебе надо понять, что принятая в этом чате методика получения списка пользователей не очень хорошая (даже можно сказать - очень нехорошая :)
Там для получения списка контактов, всем клиентам рассылается команда "Отправь на сервер свой логин". А должно быть иначе:
при входе клиента в чат, его логин и пароль добавляются в список LOGPASList:TStringList; (LogPasList.Add(Login+"="+Password);)
при отключении/выходе этот логин удаляется из LogPasList"а
а в нужный момент, когда необходимо клиенту отправить список пользователей, ему просто будет необходимо отправить левую часть (до знака "=") каждой строки LogPasList"а.
А насчёт того, что при каждом коннекте или дисконнекте клиента, всем остальным будет рассылаться полный список... Стоит ли беспокоиться из-за этого ? Особо много траффа это не сожрёт.
Хотя конечно можно не полный список всем рассылать, а только ЛОГИН НОВОГО/ОТКЛЮЧИВШЕГОСЯ КЛИЕНТА (со спец командой), а самому этом клиенту - "виновнику торжества" полный лист... в-общем, как уже сказал Подгоретский.
← →
Anatoly Podgoretsky (2002-09-27 10:07) [5]Естественно надо иметь возможность "Обновить весь список"
← →
megatrend (2002-09-30 13:19) [6]Спасибо за ответы. Я вот переползаю на этот чат с чата-NMMsg. При использовании NMMsg открытие сокетов происходит при отправке каждого сообщения, а здесь сокеты открываются при начале работы 1 раз.
Хотелось бы знать, как будут влиять "падения" сети на работу чата? Как открытый на клиенте сокет отнесется к тому, что в период его бездействия свяхь с сервером временно прерывалась?
← →
VID (2002-09-30 19:31) [7]Прервалась связь - возникнет событие onDisconnect или onError.
В onError пиши
Client.Socket.Disconnect(Socket.SocketHandle);
Поэтому необходимо реализовать механизм реконнекта.
Он был уже описан мною в этой конфе, поищи на страницах...
← →
megatrend (2002-10-01 10:46) [8]2 VID : Поиском не нашел этот механизм реконнекта. Видимо, форум индексируется не сразу.
← →
VID (2002-10-01 10:54) [9]Var CanConnect:Boolean = False;
timer1.interval = 10000;//10 sec
procedure ConnectBtnClick;
begin
CanConnect:=True;
Client.open;
end;
Procedure DisconnectBtnClick;
begin
CanConnect := False;
Client.Close;
end;
procedure ClientonDisconnect;
begin
IF CanConnect then Timer1.Enabled := True;
end;
Procedure ClientonError;
begin
Client.Socket.Disconnect(Socket.socketHandle);
IF CanConnect then Timer1.Enabled := True;
end;
Procedure Timer1Timer;
begin
Timer1.Enabled := False;
Client.open;
end;
← →
megatrend (2002-10-02 18:22) [10]Спасибо. А чем отличаются значения свойства "режим" компонента Tsocketserver - ThreadBlocking от NonBlocking?
← →
megatrend (2002-10-07 10:50) [11]?
← →
VID (2002-10-07 12:28) [12]Тем что в режиме stThreadBlocking для каждого нового клиента создаётся отдельный поток, в котором и происходит получение пакетов от клиента, и вообще большая часть работы с клиентом может происходить в этом доп.потоке. А в режиме stNonBlocking вся работа с клиентами осуществляется в основном потоке приложение, что в конечном счетё может приводить к "торможению" сервера.
← →
megatrend (2002-10-07 12:45) [13]А надо как-либо переписывать код, чтобы в один прекрасный день перейти с одного режима на другой (например, с NonBlocking на stThreadBlocking)? Или Дельфи все сделает сама?
← →
VID (2002-10-07 13:55) [14]ещё как надо. Поэтому лучше начинать с stThreadBlocking
Страницы: 1 вся ветка
Форум: "Сети";
Текущий архив: 2002.12.02;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.008 c