Instant Messenger aneb jakou cestu zvolit   zodpovězená otázka

VB.NET

Zdravím,chtěl bych pro sebe a své kolegy zkusit vytvořit instant messengera. Jen moc nevím jakou cestou se vydat.

Nejde o to že bych neuměl spojit dva počítače po síti a poslat si nějáká data, ale spíš mi jde o to jakou se vydat cestou, abych si nezadělával na problémy.

O co se tedy chci pokusit:

-mělo by se jednat o jednoduchý IM. Bude využíván pouze v rámci podnikové sítě kde jsou všechny počítače v doméně a všichni uživatelé se přihlašují pod svým doménovým účtem

-aplikace musí běhat na .Net 2

-nehodlám posílat soubory, nechci dělat audio ani video přenos, chci posílat jenom prostý text. Vrcholem by měla být pouze hromadná konverzace.

-chtěl bych se vyhnout nutnosti mít nějaký server, přes který by se zprávy posílaly. Chtěl bych se spojovat přímo.

A jak si to představuju? Použití by se mělo jednoduchostí blížit kreslící tabuli. S tím rozdílem, že jsem přemýšlel o tom, že bych neudržoval stálé spojení. Připojím se-pošlu zprávu-odpojím se. Tím pádem protějšek bude moci na stejném portu příjmat zprávy i do jiných uživatelů. Jen bych musel vytvořit cosi jako frontu s tím, že pokud se mi nepodaří připojit napoprvé, zkustím to ještě x krát (protože protějšek může zrovna data příjmat od někoho jiného) a pokud ani na x tý pokus neuspěju, tak usoudím že protějšek je offline.

Tím by odpadla nutnost vytvořit další spojení na dalším portu když bych příjmul jednoho klienta. Všechna komunikace by mohla probíhat na jednom portu, protože by byl hned po přijetí zprávy uvolněn.

Zjišťování zda jsou lidé z mého kontakt listu online, nebo offline (v kontakt listu je budu mít uložené pod jejich doménovým jménem) bych chtěl realizovat podobně, jako hry určené pro hraní po síti zjišťují, zda nějaký hráč nezaložil hru. Bohužel teď přesně nevím jak to funguje, protože toto řešení nemůžu nalézt, ale vím určitě že jsem četl článek, ve ktérém byl postup. Jde o to že se poslal požadavek na nějakou specifickou IP adresu na určitém portu, a všechny PC v rámci sítě které na tomto portu poslouchají pošlou zpátky odopvěď. Takto by mi odpověděli všechny instance mé aplikace co by v rámci vnitřní sítě byly spuštěné a já bych si vyfiltroval ty, které bych měl ve friend listu. Tento proces bych opakoval třeba každých 30 sekund a tím refreshoval dostupnost mých kontaktů (zde si ale nejsem jistý zda by to příliš nevytěžovalo síť).

Chtěl bych radu zda moje úvahy jsou správné nebo úplně zcestné (například zda nebude nutné použít server), popřípadě jak by to řešil někdo zkušenější.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Bez serveru to půjde dost těžko. Jak chcete synchronizovat seznam kontaktů? Při nejhorším lze někam jen vystavit například XML soubor se seznamem kontaktů s přidruženým uživatelem domény. To ale už znamená, že někde bude server.

Komunikaci pak zajistíte pomocí UDP pro rozpoznávání počítačů, které jsou online a komunikace TCP/IP pak navážete s konkrétním PC ve chvíli, kdy chcete začít komunikovat.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Myslel jsem že synchronizace se vyřeší tím posláním požadavku do celé sítě. Vrátí se mi seznam IP adres na kterých je spuštěna moje aplikace.

Nebo jak se to řeší u těch Lan her (v případě že není použitý dedikovaný server) ? Třeba tři lidé založí hru a nějak ji pojmenují, já se budu chtít k nějáké připojit, tak se mi zobrazí ty 3 hry i s jejich jmény a já si jen vyberu ke které se připojím.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Zjištění online stavu lidí se dělá tak, že pošlete zprávu na tzv. broadcast adresu - 255.255.255.255 a určitou chvíli čekáte na odpovědi.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Proboha..vyhněte se používání této default broadcast adresy.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

A máte alespoň jeden rozumný důvod proč?

Záleží samozřejmě na konkrétní situaci, ale je zbytečná práce zjišťovat masku aktuální sítě a dopočítávat lokální broadcast (možná je na to nějaká funkce).

Stejně každý router šíří broadcasty jen do vnitřní sítě a ven je nepustí, a ten paket bude muset zpracovat tak jak tak.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Tak treba proto, ze je to povazovano za nepatricne a operacni system by pro takovy broadcast mohl pozadovat vyssi prava :-)

Spravny programator se potrebe takoveho opravneni vyhne pokud to pujde.

Ale samozrejme, jestli setrvavate u Windows XP ... zrejme takovehle problemy resit ani nepoterbujete.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

"ze je to povazovano za nepatricne"

Kým? Od nikoho jiného než od vás jsem to neslyšel.

"operacni system by pro takovy broadcast mohl pozadovat vyssi prava"

Mohl by, ale nepožaduje. Projde mi to na Windows XP i na Windows 7 i s omezenými právy.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

No pokud se tu sejdou uz dva nezavisle hlasy, zrejme to nebude az tak neznama vec ...

Ono to vysvetleni nebude asi moc jednoznacne - jde o to ze z teorie veci by se takovy broadcast siril napric vsema sitema nekontrolovatelne. Proto byl tedy oznacen za Limited - routery ho nepropaguji vicemene vubec a operacni systemy se ho snazi eliminovat potrebovu vyssich prav. V praxi tim asi nic zasadniho clovek nezkazi, presto je to proste "spatne". Broadcast s udanym subnetem ma tu vyhodu, ze i kdyz treba projde prez par routeru, nebude prudit v jine siti nez v te, do ktere byl namireny, a soucasne pocitace, ktere budou na stejnych kabelech, si snadno odfiltruji takovy packet prave podle subnetu (podle fyzicke adresy to nelze, neb je ff:ff:ff:ff:ff:ff). Tedy jeho sireni je znacne vymezene na relativne malou skupinu cilovych adres.

Jinak druha kontroverze broadcastu je samozreme v tom, ze zatezuji vschny pocitace (neb nejde filtrovat podle mac - respektive subnetu pozdeji). Kdyz se to prezene, muze takova pekna broadcastova boure na siti udelat opravdu velky neporadek. To, ze se to povazuje za dosti nestastne reseni, ukazuje i fakt, ze nova verze IP protokolu IPv6 broadcasty nema vlastne vubec.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Můžete zkusit použít věci ze System.Net.PeerToPeer, potom to půjde i bez serveru.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Díky za nakopnutí

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Co se tyka te poznamky o prijimani zprav na stejnem portu ....

Naprosto bezne chovani socketu po prijeti TCP spojeni, je vytvorit novy socket s naprosto odlisnym portem a serverovy socket / socket co nasloucha muze dale cihat na dalsi prichozi spojeni.

Existujici spojeni se pak muze klidne tvarit jak chce, ale dokud je spojene, je docela jedno jak - listen socket rusit nemusi.

Jinak k predstave pripojovani a odpojovani...

Rozhodne byh nesel cestou vytvareni spojeni pro kazdou zpravu. Zavedl bych takove male session pro "blok hovoru", ktere by po delsi dobe neaktivity vyprseli.

Decentralizace site, distribuovane seznamy kontaktu, atd atd. To sou rozhodne zajimave vecicky. Ta decentralizace se v ramci LAN (tedy zejmena v ramci jednoho subnetu) da delat UDP broadcastingem, jak uz tady padlo. Neni to nic sloziteho a funguje to dobre. Ostatne na tom stavi mnoho elementarnich protokolu.

Distribuovany seznam kontaktu - to uz je zajimavejsi vyzva - existuje hodne systemu, ktery se takhle musi kontaktovat a oznamovat si zmeny - jako priklad treba synchronizace routovacich tabulek mezi routery, nebo treba nejnovejsi schopnosti oblibeneho BitTorrentu (fungovani bez trackeru/serveru).

Mas nekolik moznosti... takhle po ranu me napadaji tri a dve popisu ...

A) Volba Sefa - klienti se na siti dohodnou kdo bude sef a ten pak sestavi presny seznam kontaktu a bude ho udrzovat tak dlouho, dokud bude bezet. Vyber sefa muze byt docela legrace - kazdy klient v siti posle UDP packet s nahodne vybranym cislem a soucasne cte packety od ostatnich. Vsichni si mysli, ze sou sef, dokud neprectou packet s vyssim cislem (nebo stejnym, pak losujou znova). Ten jedinej, kterej si mysli, ze ma nejvyssi cislo, je sef (muze se o tom utvrdit nejakym dalsim kolem potvrzeni) a zacne sestavovat seznam lidi ... jelikoz prave zrejme dostal pri volbe sefa hromadu odpovedi od dalsich pocitacu, ma dokonce okamzite k dispozici seznam potencialnich cilu, kterych se muze ptat na Nickname atd atd. Kdyz se sef nebude dlouho hlasit, klienti si vyhlasej nove volby. No proste a jednoduse nebude jeden pevnej server pro kontakty - server bude moct byt kterykoliv z klientu. Nove prichozi klient si pak sefa vyhleda broadcastem a ten mu sam odpovi (pokud ne, je cas na volby :-)).

B) Ta jednoduzsi varianta je opet prez Broadcasty - proc nerict klientum aby cas od casu zahlasili ve svejch broadcastech i svoje jmena ... kazdej si je odchyti a zapamatuje, neni to dokonale a ma to sve nevyhody v trosku nehezkem zaplavovani site, ale s trochou rozumu to mala LANka prezije hrave.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Ten první odstavec jsem nepochopil. Budu se připojovat třeba na socketu 1234 a cílová strana mě může přímo přesměrovat na jiný socket tak, aby výchozí 1234 zůstalo volné pro další pšíchozí spojení? Pokud ano tak na volající staně musím něco udělat nebo to je automatické?

A nebo se připojím na socket 1234 a na druhé straně budu mít připravenou proceduru která mi třeba pošle zprávu díky že ses připojil, ale tady máš číslo socketu co sem ti právě vygeneroval, připoj se na něj a pak protistrana ukončí spojení?

Jinak jsem přemýšlel že bych to udělal ještě jinak. Přeci jen bych použil server ale řešil bych to přes UDP. Tzn. nemusel bych udržovat spojení a veškerá komunikace by pro všechny aplikace probíhala jen na jednom portu. (teda asi na 2, na jednom by se posílaly zprávy a na druhém informace o přihlašování/ohlašování uživatelů, změny statusů apod). Jen netuším, jak moc s přibývajícím počtem uživatelů poroste riziko, že data nedorazí protože server se bude zabývat zrovna daty jiného uživatele (třeba co to udělá když by najednou komunikovalo 100 uživatelů-i když takové využití nepředpokládám, ale jeden nikdy neví).

Jinak System.Net.PeerToPeer které tu zmiňoval pan Linhart použít nemohu, musí to běhat na .Net 2

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Když se vrátím na začátek, je vůbec nutné znovu vymýšlet kolo? Proč nepoužít některý z obrovského množství IM klientů?

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět

Programatorsky trening :-) co na tom, ze je nesmysl si davat za cil, ze prvni pokusnou implementaci nekde opravdu nasadi ... hlavni je, ze si to ozkousi :-D tu zkusenost mu uz pak nikdo nikdy nevezme ... snad az na toho nemce, co lidem schovava veci

nahlásit spamnahlásit spam -1 / 1 odpovědětodpovědět

Tohodle IM chci dělat hlavně proto, abych víc proniknul do síťové komunikace, tedy jako cvičení. Pravda je že bych se chtěl dobrat k nějáké použitelné verzi.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Doporucuju se kouknout na nejake kratke pokusne ukazky server-klient aplikaci ... a poradne si prohlednout parametry socketu behem a po prijmuti spojeni. Tam bude dobre videt jak se to chova, jake to bude mit okamzite parametry atd atd.

Vesmes se to muze chovat takhle ...

Otevres socket na nejakem portu a poslouchas (otazka par radku). Socket ceka az prijde nejake spojeni (tedy nejdrive dojde na Listen a pak Accept) a kdyz prijde, udela mitozu - tedy udela svuj klon a tomu preda rizeni toho otevreneho spojeni. To se deje vesmes automaticky.

Dim mySocket As Socket = listeningSocket.Accept()

Tady je primo videt, ze produktem (navratovou hodnotou) funkce Accept je nejaky "novy" socket. Tenhle socket bude mit na starost nove vytvorene spojeni a soucasne nebude blokovat ten listen socket na danem portu (1234 muze byt dale pouzivane pro prijem). Coz rovnou i napovida, ze ta implementace to dela automaticky - vesmes neni poterba extra resit.

Jinak jeste pro informaci, funkce Accept vybere jedno prichozi/cekajici spojeni z FRONTY a prijme ho ... to napovida, ze tedy na jednom portu lze prijmout vice spojeni a taky to, ze accept je poterba volat opakovane (smycka).

Z pohledu klienta (toho co se pripojuje) nic resit neni poterba. Na jeho strane je to transparentni vecicka. Pripojuje se na jeden port ... a jak to komunikuje pote je dost jedno - hlavne ze to komunikuje

UDP

...neni nic jako UDP spojeni, bacha na to. UDP taky nezarucuje doruceni a spravne poradi. Tedy aby byl takovy protokol korektni, je potreba nejako potvrzovat (aby se zajistilo, ze se kusy komunikce neztraceji - ok pro LAN by to nemelo zase az tak hrozit), ze packety dosli a nejako je cislovat (na tohle zase existuje tuna postupu). Ja bych samotnou komunikaci na UDP nedaval, zustal bych u primeho spojeni pomoci TCP (at uz pomoci serveru ci P2P).

Jakmile mas sever, se kterym udrzujes jedno TCP spojeni z kazdeho klienta, neni treba zadne UDP hledani, zadne broadcasty, vsechny zpravy at ty "textove" nebo "provozni" protlacis skrze to jedno spojeni a je to. Takhle to ostatne dela treba ICQ.

Narocnost neni tak hrozna dokud clovek neudela nejakou botu - stovku vzajemne hovoricich klientu jde obslouzit docela dobre, protoze jde o malicke textove zpravy, ktere chodi v relativne dlouhych prodlevach ....

Snad sem to moc nezamotal ... pokud ano, zkusim konkretneji popsat ruzne casti ...

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Ohledně toho UDP jsem se špatně vyjádřil, samozřejmě tam žádné spojení není. To se mi na tom právě také líbilo. Je ale pravda, že věci jako potvrzení o doručení druhé straně bych si musel napsat sám.

Ohledně toho vysvětlení, děkuji za něj určitě se bude hodit. Jinak jak poslouchat a příjmout klienta přes TCP vím, je to pěkně popsáno v kreslící tabuli na tomto webu.

Děkuji za ten příklad, tohle mě nenapadlo. Zítra to zkusím.

nahlásit spamnahlásit spam 0 odpovědětodpovědět
                       
Nadpis:
Antispam: Komu se občas házejí perly?
Příspěvek bude publikován pod identitou   anonym.
  • Administrátoři si vyhrazují právo komentáře upravovat či mazat bez udání důvodu.
    Mazány budou zejména komentáře obsahující vulgarity nebo porušující pravidla publikování.
  • Pokud nejste zaregistrováni, Vaše IP adresa bude zveřejněna. Pokud s tímto nesouhlasíte, příspěvek neodesílejte.

přihlásit pomocí externího účtu

přihlásit pomocí jména a hesla

Uživatel:
Heslo:

zapomenuté heslo

 

založit nový uživatelský účet

zaregistrujte se

 
zavřít

Nahlásit spam

Opravdu chcete tento příspěvek nahlásit pro porušování pravidel fóra?

Nahlásit Zrušit

Chyba

zavřít

feedback