Costruire una semplice chat in PHP non è affatto semplice.

MarcoGrazia

Utente Attivo
15 Dic 2009
686
8
18
58
Udine
www.stilisticamente.com
Ciao, devo... cioè dovrei :D costruire una seplice chat in PHP; non voglio prenderne di già pronte perché o troppo semplici al limite dell'insicurezza e del poco utilizzo, ne troppo complesse perché inutili per il mio progetto, così ho deciso di realizzarne una da me, tanto ne ho le competenze... be credevo di averne a sufficienza, ma in realtà non è affatto semplice :crying:

Sto realizzando un sito per un GDR ( Gioco di ruolo ) a fondo perduto, in pratica voglio solo tenermi in esercizio, nessnu problema col sito in se ma mi ci vuole una chat con determinate caratteristiche: in php per essere facilmente integrata all'interno delle pagine, con la possibilità di avere "stanze" e che sia di implementazione semplice e da integrarsi col database che gestisce l'intero gioco.

Detto e non fatto, cioè ho delle idee, alcune le ho messe anche in pratica in qualche prova fatta in locale ma ci sono dei punti che non mi tornano, ad esempio come si fa a leggere il database per inserire nel rullo dei messaggi quelli scritti dagli utenti, valutando solo gli ultimi senza ripetersi?

Avevo pensato ad un loop continuo in cui gli utenti loggati venivano messi in uno stack; i messaggi ovviamente vengono inviati in modo casuale ma vengono messi in coda prima di entrare nel database, uno stack del tipo l'ultimo a entrare aspetta il turno :D
Ma la tecnica è semplice in fondo, l'utente della chat scrive un messaggio che arriva allo stack, da qui viene scritto nel database nel momento che arriva il suo turno, una volta iscritto questo viene mandato anche a tutti i rulli di tutti gli utenti iscritti.
A parole un sistema potrebbe anche funzionare, il database potrebbe sembrare inutile ma serve per avere uno storico dei messaggi.
Ovviamente non parlo dell'implementazione di login e logout perché non è questo il punto.

Voi come fareste?
 

MarcoGrazia

Utente Attivo
15 Dic 2009
686
8
18
58
Udine
www.stilisticamente.com
Una forma semplificata al massimo è questa, ovviamente è solo un embrione e non funziona nemmeno bene.
Il file client.html
HTML:
<!DOCTYPE html>
<html lang="it">
<head>
	<meta charset="utf-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>Chat</title>
</head>
<body>
	<div id="rullo"></div>
	<label for="comandi">Comandi: </label>
	<select id="comandi">
		<option value="0">NULL</option>
		<option value="q">EXIT</option>
	</select>
	<label for="messaggio">Messaggio: </label>
	<input type="text" id="messaggio" value="">&nbsp;
	<input type="button" id="invia" name="invia" value="INVIA">

	<script src="jquery-1.11.3.min.js"></script>
	<script>
		$( '#invia' ).on( 'click', function() {
			var c = $( '#comandi' ).val();
			var m = $( '#messaggio' ).val();
			if ( m != '' ){
				var dati = { 'data': m, 'comandi': c };
				$.getJSON( 'server.php', dati, function( data ){
					var items = [];
					$.each( data, function( key, val ) {
						items.push( "<li id='" + key + "'>" + val + "</li>" );
					});
					$( "<ul/>", {
						"class": "my-new-list",
						html: items.join( "" )
					}).appendTo( '#rullo' );
				});
			}
		});
	</script>
</body>
</html>
Il file server.php
PHP:
<?php
	if ( filter_has_var( INPUT_GET, 'data' ) && filter_has_var( INPUT_GET, 'data' ) != '' ){
		$stop= true;
		$messaggio = filter_input( INPUT_GET, 'data', FILTER_SANITIZE_STRING );
		$comando = filter_input( INPUT_GET, 'comandi', FILTER_SANITIZE_STRING );
		while( $stop ){
			sleep( 1 );
			$msg = array( 'messaggio' => $messaggio );
			if ( $messaggio == '/quit' || $comando == 'q' ) {
				$msg =  array( 'messaggio' => 'utente uscito' );
				$stop = false;
			}
			echo json_encode( $msg );
		}
	}
?>
In realtà se lancio il client e scrivo qualche cosa, il server si attiva ma non ritorna nulla, forse nu problema di polling? Non so, ci ho messo uno sleep di un secondo per rallentare il ciclo ma bo, non funge, invia solo il messaggio di 'utente uscito' se mando il comando di quiet ( q ).
Se richiamo direttamente server.php ( per questo ho usato la GET ) con server.php?data=ciao ovviamente lo schermo mi si riempie di { 'messaggio' : 'ciao' } all'infino, almeno fino a quando o va in crash per esaurimento dello spazio data della memoria assegnata dal server allo script, o do il comando Q a quel punto esce con la scritta 'utente uscito'.

Ora come ora mi basterebbe capire come mai il server non ritorna nulla!

Rettifico parzialmente, come detto prima lo script risponde così, anche se non appare nulla nella casella del rullo:
{"messaggio":"ciao"}{"messaggio":"ciao"}{"messaggio":"ciao"}{"messaggio":"ciao"}{"messaggio":"ciao"}{"messaggio":"ciao"}{"messaggio":"ciao"}{"messaggio":"ciao"}{"messaggio":"ciao"}{"messaggio":"ciao"}{"messaggio":"ciao"}{"messaggio":"ciao"}{"messaggio":"ciao"}{"messaggio":"ciao"}{"messaggio":"ciao"}{"messaggio":"ciao"}{"messaggio":"ciao"}{"messaggio":"ciao"}{"messaggio":"ciao"}{"messaggio":"ciao"}{"messaggio":"ciao"}{"messaggio":"ciao"}{"messaggio":"ciao"}{"messaggio":"ciao"}{"messaggio":"ciao"}{"messaggio":"ciao"}{"messaggio":"ciao"}{"messaggio":"ciao"}{"messaggio":"ciao"}<br />
<b>Fatal error</b>: Maximum execution time of 30 seconds exceeded in <b>C:\Apache\users\marco\prova\chatta\server.php</b> on line <b>8</b><br />
Ma è ovvio come ho detto prima, lo spazio script viene chiuso preventivamente prima che vada in crash, la riga 8 è: $msg = array( 'messaggio' => $messaggio ); ma è un punto arbitrario, ovvero quando lo script è stato chiuso si trovava a quel punto.
 

alankanz

Lupacchiotto
Membro dello Staff
MOD
18 Giu 2014
135
0
16
Roma
Ciao MarcoGrazia,

La chat deve essere in tempo reale? cioè quando invio il messaggio arrivi istantaneamente a tutti gli utenti della chat?