Най-простият чат на idTCPServer
Ще има специален сървър и куп клиенти за чат. Въпрос: клиентът ще има ли нужда от двата компонента - idTCPClient (за предаване) и idTCPServer (за приемане)? Или е възможно по някакъв начин да настроите idTCPClient да чака входящи съобщения? Ако съм разбрал всичко правилно, това е невъзможно.
вижте как се прави в примери за Indy (IndyDemos\Chat\Client)
he има таймер за половин секунда, readln се извършва в него с таймаут от 5 ms. т.е. съобщенията ще пристигат с максимално закъснение от 0,5 секунди. такова забавяне е недопустимо за мен и не искам да държа потоците отворени, защото се очакват много клиенти.
> досега се спрях на идеята за настройка на всеки клиент на > idTCPServer"y.Не можете да измислите по-глупава идея. Какво не ви харесва в стандартния механизъм? След момента на свързване концепцията за клиент и сървър престава да съществува. Има установена връзка, в двата края на която можете да изпращате и получавате данни.
Да, но как да го внедрите на TIdTCPClient? Компонентът TTCPClient има събитие OnReceive, но TIdTCPClient не. Трябва да зададете таймер и да направите ReadLn с изчакване. Освен това ще трябва да инсталирате TIdAntiFreeze, така че приложението да не замръзва. В този случай съобщенията до клиента ще идват с дискретността на таймера. Наистина ли всички го правят? Или има по-добър начин?
Абстрактен въпрос: защо не сте доволни от интервала от половин секунда?
за чат в локална мрежа с интерактивни игри (викторина, мафия и други), половин секунда е много.
Добре сложи 100 ms.
Първо: какво да напиша в манипулатора на таймера? Readln? И ако клиентът получи 2 съобщения? Тогава той ще получи вториявтората операция на таймера? И ако му бъдат изпратени 100 реда от буфера? Ще ги получи ли след 10 секунди? Второ: Не обичам отворените връзки. Те зареждат процентите на сървъра и бъгът при тях е следният: ако компютърът на клиента увисне, връзката ОСТАВА ОТВОРЕНА. Трябва да въведете допълнителна команда ping. И ако клиентът получи съобщение след замразяване, но преди ping, тогава обикновено започват проблеми (заради това програмният сървър се срива за мен). И трето: в допълнение към чата се планира да се вгради мини-файлов сървър в клиента, така че най-логичният изход е да инсталирате TIdTCPServer. Ако някой има коментари, поправете ме.
А ако му бъдат изпратени 100 реда от буфера?И ако му бъдат изпратени 100 реда, тогава направете ReadLn в цикъл до първия празен ред. Изключете таймера, докато обработвате получения отговор. Обработена е получената команда - включете го отново. Още фантастика и проблемите ви ще изчезнат.Не харесвам отворените връзки.Не. Но идеята ви със сървърен компонент на клиента за чат съобщения има недостатък: сървърът няма да може да отвори връзка към такъв клиент, за да изпрати друго съобщение, ако клиентът е под прокси. Ако искате файлов сървър на клиента, инсталирайте и TIdTCPServer, никой не си прави труда да има друг компонент за конкретни задачи.връзката ОСТАВА ОТВОРЕНА. сървър от страна на клиента.И ако клиентът получи съобщение след затваряне, но преди ping обикновено започват проблеми (заради това сървърът на prog се срива за мен).Не знам как организирате ping на сървъра и изпращането на съобщения, но не виждам никакви проблеми в тази ситуация.Освен това ще трябва да инсталирате TIdAntiFreezeКакво не ви харесва в TIdAntiFreeze? Удобен компонент, премахва основния проблем, когаторежим на блокиране.
така че .. веднага духайте тук http://book.itep.ru четете-разбирайте, докато станете напълно просветени по отношение на TCP протокола и Winsock
защото това което казваш е глупост
имам почти същия проблем.
процедура TForm1.IdTCPServer1Execute(AThread: TIdPeerThread); var s,sIP,sCommand1,sCommand,sOldNick,sNewNick: низ; i,k:integer; a:IPNames; begin try sCommand:=AThread.Connection.ReadLn; s IP:= AThread.Connection.Binding.PeerIP; Ако дължина(sCommand)>0 тогава BeGiN . . . EnD; освен begin Append(FLogs); Writeln(FLogs," Exception on Server.Execute "+sIP+": "+sCommand); Затваряне на файл (FLogs); IdTCPServer1.ThreadMgr.ReleaseThread(AThread); край край; край;
Понякога чатът работи половин ден без проблеми, понякога виси на всеки половин час. Регистрирам се навсякъде и първата грешка винаги идва от тук. След това съобщенията за грешка се появяват на други места.
Ако не сте твърде мързеливи, моля, изпратете пример за IndyDemos\Chat на [email protected]. Аз съм на Delphi 6, не е там.
Какво страдаш. Използвайте ICS компоненти (http://www.overbyte.be). По-добри компоненти за работа с мрежата не се срещнаха. Инди също не е лош. но в определени неща. Написал съм доста за тези компоненти. Можете лесно да внедрите многонишков сървър, който перфектно ще се справи със задачите и ще обработва данните възможно най-бързо, тъй като данните от клиентите пристигат.
По едно време, когато започнах да пиша моя чат, избрах на каква база да го направя или със собствените си ръце чрез сокетите API. Или използвайте готов компонент. Стигнах до извода, че не си струва да изобретяваме колелото в този случай. Опитах много съставки. И се спря на ICS като най-многообмислен и лесен за използване и адаптиране към конкретен проект. И не съжалявам. Компонентът е просто страхотен (говоря за TWSocket) и реализацията на сокета от ISC. Освен това в доставката на компонента има много примери за всички случаи. Освен това постоянно се актуализира + FWS.
versНе разбрах въпроса. Защо да поставите idTCPClient в режим на готовност? Използвайте idTCPServer, за това е създаден! И всички извращения с таймери ще сринат програмата ви, когато броят на клиентите е повече от два (или когато един от потребителите забрави да пусне Enter за 2 секунди, когато изпраща съобщение) поради десинхронизация. idTCPServer поддържа многопоточност много добре. Можете да синхронизирате с процесорна процедура с един мютекс (събитие / критична секция).
> клиентът има ли нужда едновременно от idTCPClient (за > изпращане) и idTCPServer (за получаване)?
защо и двете? idTCPClient е основната част от връзката, idTCPServer е сървърната част, което следва поне от името
и тази друга част "може" както да предава, така и да получава данни
точно обратното - те обикновено го пазят, защото "обикновените" чатове (каквито има куп в мрежата) са чатове, които използват http . http е приложен протокол, базиран на TCP транспортния протокол, който предполага (!) постоянна връзка между клиента и сървъра
> инициализирайте TCPServer връзката", ако е възможно, тогава > това е извращение
>> инициализирайте TCPServer връзката", ако е възможно, тогава >> е извращение
можете да инициирате връзка от TCPServer "и към сървъра :)
означава ситуацията, когато един TCPServer стане клиент на друг TCPServer?
глупости. втова е невъзможно с обикновена реализация, защото или connect() или bind()+listen() .. но не и двете едновременно
Съжалявам, обърках се :) Погледнах в изходния код, там сървърната програма създава динамичен клиент за свързване към сървъра нагоре.
в ! това е съвсем различен калико) и точно от този калико са зашити почти всички приложения, които изпълняват поне функциите на същия прокси сървър
И в този въпрос ми се струва, че говорим за LAN chat, които рядко са базирани на http - не съм срещал.
Говорих за LAN-чат essno. :) Също така правя динамично създаване на idTCPClient.