Diskuze: Jak udělat místnosti v chatovací aplikaci
V předchozím kvízu, Online test znalostí PHP, jsme si ověřili nabyté zkušenosti z kurzu.

Tvůrce

Zobrazeno 13 zpráv z 13.
//= Settings::TRACKING_CODE_B ?> //= Settings::TRACKING_CODE ?>
V předchozím kvízu, Online test znalostí PHP, jsme si ověřili nabyté zkušenosti z kurzu.
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...
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?
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)).
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?
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áš.
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.
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ý 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.
Javascript pri zavreni okna zachytava udalost window.onbeforeunload.
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.
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
jeste jsem nasel tuhle verzi
/…rver_min.txt
/…_chat_min.js
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.
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.
Zobrazeno 13 zpráv z 13.