Body zdarma Java týden
Využij podzimních slev a získej od nás až 40 % bodů zdarma! Více zde
Pouze tento týden sleva až 80 % na Java e-learning!
Avatar
Milan Turyna
Redaktor
Avatar
Milan Turyna:26. srpna 17:16

Dobrý den, vytvářím anonymní chat aplikaci, a potřebuji nějak vytvořit místnosti v této chatovací aplikaci, její systém funguje na principu, že se přihlásíte, zobrazí se vám veřejná místnost, a při odhlášení se Vaše údaje z databáze odstraní, proto to je anonymní, můžete se přihlásit kdykoliv za jakýkoliv nick. A chtěl bych docílit toho, že by moje aplikace měla podobný systém místností jako systém discord invite, a serveru. (Slovo systém tady používám s významem jako struktura nebo tak nějak, prostě jak je to udělané, jak to funguje atd.).

Tudíž by se zobrazilo pod věřejnou roomkou nějaké tlačítko na výtvor vlastní roomky, kde by identifikační kod/klíč, a pod tím by se ostatní uživatelé aplikace mohli přihlásit do jeho roomky (byl by tam input pro vložení klíče, jediná roomka která by se zobrazovala automaticky by byla veřejná, mnou vytvořená (která tam nyní už je)).

Problém je v tom že vše ostatní byla proti tomuto byla "hračka", ale u tohohle absolutně nevím vůbec ani jak to udělat. Napadlo mě přes $_GET nějak šikovně, jenže absolutně ani nevím jak udělat strukturu databáze která by fungovala, podle mých představ, vím že vytváření tabulek pro každou roomku by bylo primitivní (sice neočekávám tolik návštevníku že by MySQL padala, ale jistota je jistota.). Moje aplikace není OOP, jelikož začal jsem jí dělat ještě při učení základních konstrukcí PHP a ostatní jsem se učil s vývojem. Potřeboval bych tedy, zjistit nějak
jakým způsobem to mám vymyslet a udělat, a jak by mohla/měla vypadat struktura databáze. Moje databáze vypadá následovně:

  • chatters
  • messages
  • banned_ip

což tabulka messages je udělaná pouze pro věřejnou room, a chatters zaznamenává aktivní uživatele (ti kteří se přihlásili.) a banned_ip funguje na principu, že mám v administračním panelu banovací systém (pro celý web, kdyby se našel někdo, kdo by se nechoval tak jak má.).

Vím že po Vás chci asi mnoho jelikož normálně bych řekl že tohle není něco pro začátečníka, ale jelikož už se mi několikrát stalo že jsem svoje projekty odložil, tak bych nechtěl udělat něco stejného i u tohohle a pokusil se ho dokončit podle svých představ.

Tudíž ještě jednou ve shrnutí:

Moje představa - chtěl bych aby po přihlášení se zobrazila veřejná roomka pro všechny a pod ní byl formulář/odkaz na formulář na tvorbu vlastní roomky, a vedle toho připojení na již vytvořenou roomku (pomocí identifikačního kodu který bude generován, při tvorbě místnosti/roomky).

Zatím to mám - po přihlášení se zobrazí veřejná roomka

Bezpečnost (sql injection, xss, spam (jak uživatelů, tak i zpráv)) mám vyřešen, to stejné odhlašování, přihlašování, ban system, administrační panel.

Přeji pěkný den.

 
Odpovědět 26. srpna 17:16
Avatar
Jan Kerhart
Člen
Avatar
Odpovídá na Milan Turyna
Jan Kerhart:26. srpna 18:49

Já bych to zbytečně nekomplikoval... Přidal bych tabulku chat_rooms, nějak takto:

CREATE TABLE `chat_rooms` (
  `chat_rooms_id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  `name` varchar(100) DEFAULT NULL,
  `code` varchar(50) NOT NULL,
  `creator` int(10) UNSIGNED DEFAULT NULL,
  `created` datetime NOT NULL DEFAULT current_timestamp(),
  `expires` int(11) DEFAULT NULL,
  PRIMARY KEY  (`chat_rooms_id`),
  KEY `FK_creator` (`creator`),
  CONSTRAINT `FK_creator` FOREIGN KEY (`creator`)
  REFERENCES `chatters` (`chatters_id`)
  ON DELETE NO ACTION
  ON UPDATE NO ACTION
) ENGINE=InnoDB;

Name jméno místnosti, code klíč kterým se uživatelé připojují do místnosti (vygeneruješ v PHP při zakládání místnosti), creator id chattera, který místnost vytvořil, created čas vytvoření (vyplní databáze), expires počet hodin, po kterém se má místnost smazat. (Pokud toto nepotřebuješ, změň na TINYINT a bude sloužit pouze pro rozlišení trvalé (veřejné) místnosti a dočasné (uživatelské) místnosti.

Do tabulky messages přidej sloupec room s cizím klíčem a ukládej ID místnosti, do které zpráva patří. Tvou veřejnou místnost přidej do tabulky chat_rooms také. Pokud by jsi chtěl veřejných místností více, tak to také není problém...

 
Nahoru Odpovědět  +1 26. srpna 18:49
Avatar
Milan Turyna
Redaktor
Avatar
Milan Turyna:26. srpna 19:15

Dekuji moc, takze databaze by fungovala na tomhle principu a v php bych to udelal pres get parametr, ktery by checknul jestli ten parametr se rovna s nejakym klicem kdyz ano tak by se nacetl chat s tim klicem?

 
Nahoru Odpovědět 26. srpna 19:15
Avatar
Jan Kerhart
Člen
Avatar
Odpovídá na Milan Turyna
Jan Kerhart:26. srpna 19:46

V podstatě ano, ale tu kontrolu a načítání bych spojil a nechal na databázi. Při výpisu všech zpráv v dané místnosti např. takto:

SELECT (potřebné sloupce z tabulky messages s prefixem `m`.)
FROM `messages` AS `m`
JOIN `chat_rooms` AS `c` ON `c`.`chat_rooms_id` = `m`.`room`
WHERE `c`.`code` = ?

A při execute prepared statementu předáš parametr z GETu (předem nezapomeň zkontrolovat, jestli existuje (isset)).

Akceptované řešení
+20 Zkušeností
+1 bodů
Řešení problému
 
Nahoru Odpovědět 26. srpna 19:46
Avatar
Milan Turyna
Redaktor
Avatar
Milan Turyna:26. srpna 19:51

Jo a ty zpravy funguji tak ze je jen jedna tabulka messages a prida se sloupec id, a budou se selectovat zpravy ktery maji ID/klic stejny?

Editováno 26. srpna 19:53
 
Nahoru Odpovědět 26. srpna 19:51
Avatar
Jan Kerhart
Člen
Avatar
Odpovídá na Milan Turyna
Jan Kerhart:26. srpna 21:11

Přesně tak, jen jedna tabulka pro všechny zprávy, ve které je sloupec room ve kterém je vždy ID místnosti do které zpráva patří. A při dotazu vždy pomocí WHERE vybereš ty zprávy, které patří do dané místnosti. A jelikož neznáš ID místnosti, ale víš jen její kód, tak nejdříve tabulky propojíš (JOIN, šel by použít i poddotaz), aby u každé zprávy byl i "virtuální sloupec" s kódem místnosti, podle kterého potom vybíráš.

 
Nahoru Odpovědět 26. srpna 21:11
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:27. srpna 7:54
CREATE TABLE `chat_rooms` (
  `chat_rooms_id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  `name` varchar(100) DEFAULT NULL,
  `code` varchar(50) NOT NULL,
  `creator` int(10) UNSIGNED DEFAULT NULL,
  `created` datetime NOT NULL DEFAULT current_timestamp(),

Ja bych se nebal pridat tam text pole popis mistnosti + boolean verejna, jina. Tak to muzes mit v jedne tabulce.
Pripadne text pole pravidla a boolean od 18 let pro mistnosti se sexualni tematikou. Podobne, jak to ma xchat.

 
Nahoru Odpovědět 27. srpna 7:54
Tento výukový obsah pomáhají rozvíjet následující firmy, které dost možná hledají právě tebe!
Avatar
Milan Turyna
Redaktor
Avatar
Milan Turyna:27. srpna 9:10

Dobrý den, děkuji, možná to přidám, ještě nevím, jelikož když to budu vytvářet tak jsem takovej, že ještě tak 3x min to změním, a finálně to je úplně jiný :D Jinak trápí mě ještě jeden problém, jelikož je to anonymní chat, tak je jen dočasné jméno a po odhlášení se z databáze vymaže, jenže problém je v tom že se může stát že expiruje session, tudíž člověk nebude přihlášen, ale bude pořád v databázi, a bude se zobrazovat že je online (mám tam takový box, s online uživateli) a mě zajímá jestli by to šlo nějak spravit, jednou mi někdo psal že by se dalo pomocí websocketů komunikovat s uživatelem a až by vypnul browser, tak by se provedl určitý příkaz/úkon, jenže nic pomocí websocketů jsem nedělal a nevím jak na to, jako dočasné řešení jsem měl přes ajax, udělaný, že při vypnutí okna se spustí PHP soubor jenže to není moc dobré řešení protože když resetnu stránku (nebo dám F5), tak se mi to odhlásí, protože to bere jako kdyby jsem odešel, tudíž mě napadá odstranit nějak session expire, a prostě dokud by se neodhlásil tak tam byl a users online bych odstranil, a nebo jestli by nějak šlo udělat, aby to neplatilo na odkazy a web této aplikace.

 
Nahoru Odpovědět 27. srpna 9:10
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:27. srpna 10:40

Javascript pri zavreni okna zachytava udalost window.onbefo­reunload.
Muzes to videt na nekterych strankach, ze ti vyskoci hlaska, zda chces rozepsanou zpravu zahodit, kdyz zmacknes alt+f4 a z nejakeho duvodu se nulozila na server. Tusim i fb to tam ma.

Web socket by sel pouzit taky. Jenze, to uz muzes cely chat resit pres websocket. A navic ne kazdy browser to podporuje. Pro websocket musi mit server povolene sockety a musis tam spustit sluzbu. Coz muze byt php kod v nekonecne smysce. Cili zvlastni privilegia, abys slo pouzit v php unlimited (set_time_limit(-1)).
Existuje jakysi websocket klient pro linux, nevim, nepouzivam, bracha by vedel vic, asi.

Rtc chat. Bracha chtel udelat rtc chat. To tez neumi kazdy browser. A k propojeni je treba pouzit nejaky program na vymenu certifikatu. Tak k tomu prave pouzil nejaky linuxovy WS. Ja zkousel alternativu v php jsem neco takoveho vygoogloval. Pro RTC je treba taky podobny server.
Tady mam nejake kody, snad se v tom vyznas.
/…_server0.txt
/…s_server.txt // vylepsena verze
/…et/index.htm
/…/rtc-chat.js
Vytahni si z toho jen ten web-socket.
Chtel jsem si udelat jednoduchy ws chat, ale uz se mi nechtelo, pak.

ws_server.txt
Funguje to tak, ze si otevres v php socket (master). A pak spustis nekonecnou smysku, ktere se snazi z toho socketu cist data. Podle toho, co tam prijde, bud otevres dalsi socket nebo jej zavres. Pri otvirani socketu odesilas jakousi propojovaci zapravu, kod, rika se tomu hanshake. html/js stranka to prevezme, vytvori odpoved, kod, hanshake a ten ti odesle. Timto kodem pak sifrujes vsechny sve zpravy. Cislo socketu a kod si ulozis do seznamu. Pri dalsi smyscce kotrolujes vsechny sockety. prevezmes zpravy a rozesles ostatnim ve skupine nebo na konkretni socket. Podle toho, jak si napises program.
PHP v tomhle resi pouze otevirani socketu, handshake, zavirani socketu, zasilani zprav. Obsah zpravy na socketu si zjistujes sam. muze jit o ping, zpravu, handskahe, odpojeni...
To same resi pak JS.
Nevim uz, zda ws nebo rtc, ale jedno z toho se mi nepodarilo odladit. Na strane php se zpravy urcite delky sifrovali jinak nez je dekodoval js :) Nedokazal jsem zjistit proc. Pouzil jsem examply. A Firefox. Tusim, ze wqs fungovalo, RTC mi neslo.

Jo, vyhoda WS chatu je, ze se prenasi fakt minimum dat proti https. Nevyhoda, ze vic lidi blokuje vic prostredku. Ale tusim i tak je to vyhodnejsi.

Editováno 27. srpna 10:41
 
Nahoru Odpovědět 27. srpna 10:40
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:27. srpna 10:44

Jo, ve tvem pripade, kdybys chtel jen hlidat otevrene okno, tak si otevres s tim clovekem socket a v okamziku, kdy prestane pingat, tak server vytvori udalost zavreni socketu a dal si to uz obslouzis sam.

Jo, takovy problem, kdyz to budes testovat. Udelej si tam nejakou moznost preruseni te smysky a uzavreni socketu po preruseni. Protoze pak budes muset ten program zhazovat jako proces a muze ti nechat otevreny socket a bude treba zhodit cele php :)

 
Nahoru Odpovědět 27. srpna 10:44
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:27. srpna 10:49

jeste jsem nasel tuhle verzi
/…rver_min.txt
/…_chat_min.js

 
Nahoru Odpovědět 27. srpna 10:49
Avatar
Milan Turyna
Redaktor
Avatar
Milan Turyna:27. srpna 12:25

Použiji cron a tento script:

$sql_delete=$dbh->prepare("DELETE FROM chatters WHERE seen+300<=?");
$sql_delete->execute(array(time()));

ještě sice nevím na jakou dobu bych měl nastavit spouštění scriptu, ale takto by to mělo fungovat, 300 = můj expiration time tudíž už session bude expirovaná, a tudíž nezáleží či je daný uživatel online nebo ne.

 
Nahoru Odpovědět 27. srpna 12:25
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:28. srpna 8:00

Expire se nastavuje podle poctu ucastniku. Treba podle php session, tusim 17 min, cas do sql rekneme 15, pro jistotu mene. Ale delete muzes nastavit jednou za 24h. A to treba bych sel i do TRUNCATE tabulka, nekdy ve 2 rano. Vyhoda je, ze se ti tusim takhle nuluje autoincrement.
Co se tyce autoodhlaseni, tak pomoci toho js eventu nebo ws to vis v podstate hned.

 
Nahoru Odpovědět 28. srpna 8:00
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 13 zpráv z 13.