# Instant Messaging / Chat in PHP (mit Ajax, Socket,...?)



## deb_ugger (9. Mai 2008)

Hallo!

Ich weiß, diese Frage wurde hier schon öfter gestellt, aber nach einem Tag Suche bin ich nun doch an dem Punkt angelagt, ein neues Thema zu erstellen. Denke es ist sicher für mehrere interessant...

Ich möchte auf einer Webseite einen Chat anbieten. Sollte jedoch eine totale Schmalspurvariante sein, in der sich lediglich 2 Benutzer untereinander unterhalten können sollen (also eher ein "Instant Messaging"). Dabei klickt man im Benutzerprofil eines Benutzers der gerade online ist auf "Zum chatten einladen", der Benutzer auf der Gegenseite bekommt eine Hinweismeldung "Chateinladung - Annehmen/Ablehnen" und schon öffnet sich ein z.B. Popup in dem die User plaudern können...

Jetzt würde ich das ganze gern in PHP umsetzen (damit kenn ich mich nämlich halbwegs aus). Die Frage ist nur, wie ich an das Ganze am Besten herangehe. Deshalb wollt ich mal bei euch anfragen, welcher Weg hier der Beste wäre. AJAX wäre natürlich eine Möglichkeit, doch halte ich von den ständigen Reloads nicht viel. Dann würde sich wahrscheinlich eine Socket-Verbindung anbieten? Damit kenne ich mich weniger aus, deshalb meine Frage, ob das hiermit funktionieren könnte?

Wäre für eure Ideen sehr dankbar!

Grüßle,
Stephan


----------



## Jacka (9. Mai 2008)

Hi!

Möchtest du das System selber programmieren oder "genügt" dir auch eine bereits fertige Lösung?
Wie wäre es mit ajaxIM?

 hat da einige interessante Treffer ergeben.

Viele Grüße,
Jacka


----------



## deb_ugger (9. Mai 2008)

An sich würde ich auch eine "fertige" Lösung nehmen, sofern anpassbar. Ich möchte halt auf überflüssige features verzichten und alles zu schmal wie möglich halten.

Es wäre natürlich gut, wenn der Server dabei nicht zu sehr belastet wird. Wenn z.B. 300 Leute gleichzeitig chatten, könnte das aufgrund des pollen ziemlich schnell zum problem werden. ich hab gerade was bzgl. Comet + PHP gefunden. Mein Wunsch wäre nämlich, dass wenn ein bei meiner website eingeloggter benutzer über dieses feature angeschrieben wird, er sofort eine hinweismeldung bekommt (über ein push --> also ohne dass er vorher die seite reloaden muss). Bei den bestehenden lösungen muss er bereit in den chat selsbt eingeloggt sein.

hier ein projekt, dass ich bzgl. Comet gefunden habe:
http://www.xajaxproject.de/2007/12/15/comet-streaming/

Hat jemand damit erfahrung? Ich werds mir mal anschaun... und meine erfahrungen posten...


----------



## Bgag (10. Mai 2008)

Hallo!
Also ich verstehe noch nicht so ganz, was du eigentlich willst. Soll das ein einfacher Chat sein, den man per Mausklick auf einen Link öffnen kann, man gibt einen Username an und los geht es, wobei per Ajax die neuen Daten von einem PHP-Script geholt werden, die in einer MySQL-Tabelle gespeichert sind. Die Daten in der MySQL-Datenbank haben alle einen Timestamp, sodass sie nach einer halben Stunde gelöscht werden können. 

Oder möchtest du eigentlich einen IRC-Client, der per PHP angesprochen wird und dann via Ajax die Regelmäßigkeit der Anfragen in das Script gebracht wird. 

Beides relativ einfach umsetzbar. Wobei man sich über die Sinnhaftigeit eines IRC-Client streiten kann. Und wenn es nicht dein eigener Server ist, würde ich mir so oder so überlegen, ob es Sinn macht ein solches Programm zu hosten, da das bei 300 Leuten gleichzeitig auf jeden Fall immense Kosten werden.
MfG, Andy


----------



## deb_ugger (10. Mai 2008)

Hi!

Ja und Ja. Der Chat braucht jetzt keine "Channels" oder sonst was, lediglich ein Gespräch zwischen 2 Leuten.

Man kann sich das so vorstellen: Auf einer Community-Seite hat man User-Profile. Man sieht, bei einem Profil, dass ein User online ist. Man klickt auf "Gespräch starten" und kann mit dem User anfangen zu quatschen.

Ich hab übrigens einen eigenen Server, ja.

Grüßle,
Stephan


----------



## RaVenC (10. Mai 2008)

Ich gehe mal davon aus, dass du ein wenig programmieren kannst..
im Anhang hab ich dir ein Grundstock für einen Ajax Chat gegeben..
Den noch ein wenig um bauen, dann hast du was du möchtest


----------



## falco2402 (10. Mai 2008)

RaVenC hat gesagt.:


> Ich gehe mal davon aus, dass du ein wenig programmieren kannst..
> im Anhang hab ich dir ein Grundstock für einen Ajax Chat gegeben..
> Den noch ein wenig um bauen, dann hast du was du möchtest



Hey, vielen Dank auch von mir, die Vorlage ist genial !!


----------



## deb_ugger (13. Mai 2008)

Hi!

danke für das Script! Hast dus auch schon mal mit Comet versucht? Ist ja zurzeit irgendwie in Mode. Hab mir mal ein paar Tutorials durchgelesen, und irgendwie klingt das schon vielversprechend. Für mich stellt sich lediglich die Frage der Serverlast. Wenn für 100 Clients sekündlich gepollt wird. Es scheint auch noch Probleme zu geben, Firefox und Internet Explorer unter einen Hut zu bringen.

http://wiki.ajax-community.de/tutorial:erste-schritte-mit-comet

Grüßle


----------



## deb_ugger (21. Mai 2008)

Hi!

Also ich bin jetzt auch zu dem Schluss gekommen, dass ein Ajax Polling wohl die einfachste und beste Lösung wäre. Letztendlich verbirgt sich hinter "Comet" ja nichts anderes. Ich hab diesbezüglich ein paar interessante Seiten gefunden und jetzt mal ein Script geschrieben, das pollt und auf eine php-Seite zugreift.

Das polling ist standardmäßig auf 10 Sekunden gesetzt.
Sobald Content geliefert wird (also z.B. der Chat beginnt), erhöht es sich auf 1 Sekunde.
Nach 20 Sekunden inaktivität geht das polling wieder auf 10 Sekunden zurück.

Funktioniert in IE und FF. Anregungen sinds stets willkommen!

index.php

```
<html>
	<head>
		<title>Ajax Polling</title>
	</head>
	<script src="polling.js"></script>
	<script>
		function initPolling() {
		 	load();
		}
		function load() {
			Ajax = new Ajax();
			Ajax.URL = "server.php?memberid=5";
			Ajax.Interval = 1000;
			Ajax.LongInterval = 10000;
			Ajax.DoBreak = 20000;
			Ajax.Feedback = MyFeedback;
			Ajax.Status = MyStatus;
			
			var now = new Date();
			document.getElementById('timelimit').value = now.getTime()+Ajax.DoBreak;
			
			Ajax.Refresh('?memberid=1');
		}
		function MyFeedback(feedback) {
		 	var now = new Date();
			var uhrzeit = now.getHours()+":"+now.getMinutes()+":"+now.getSeconds();
			Connection.innerHTML = feedback+" - "+uhrzeit;
		}
		function MyStatus(status) {
			Feedback.innerHTML = status;
		}
	</script>
	<body>
		<div id="Connection"></div>
		<div id="Feedback"></div>
	</body>
	
	<input type="hidden" id="timelimit" value="" />

	<script>
	window.onload = initPolling;
	</script>
</html>
```

server.php

```
<?php
	echo date("H:i:s",time())." id=".$_GET['memberid'];
?>
```

polling.js

```
function Ajax() {

	var timeoutID;
	var param;
	var polling;
	var Interval = 1000; // 1 sec. poll mode
	var LongInterval = 10000; // 10 sec. poll mode
	var DoBreak = 20000; // 20 sec. inactivity
	var xmlhttp = CreateXMLHttpRequest();

	function CreateXMLHttpRequest() {
		if (window.ActiveXObject) {return new ActiveXObject("Microsoft.XMLHTTP"); } 
	   	if (window.XMLHttpRequest) {return new XMLHttpRequest(); } 
		return null;
	}

	this.Start = function() {
		if(!polling)
			polling = setTimeout("Ajax.Refresh()", Ajax.Interval);
	}

	this.Stop = function() {
		clearTimeout(polling);
		polling = null;
		Ajax.Feedback("<font color=red>Disconnected...</font>");
	}	
	
	this.Refresh = function() {
		if(xmlhttp) {
			if(!this.CallInProgress(xmlhttp)) {
				xmlhttp.open("GET", Ajax.URL, true);
				
				xmlhttp.onreadystatechange = this.ChipmunkResponse;
				
				xmlhttp.setRequestHeader("Pragma", "no-cache");
				xmlhttp.setRequestHeader("Cache-Control", "must-revalidate");
				xmlhttp.setRequestHeader("If-Modified-Since", document.lastModified);
				
				
				xmlhttp.send(null);
				timeoutID = setTimeout('Ajax.OnTimeout()', Ajax.Interval);

			} else {
				Ajax.Feedback("<font color=red>Slow Connection...</font>");
			}
		} else {
			Ajax.Feedback("<font color=red>Disconnected...</font>");		
		}
		polling = setTimeout("Ajax.Refresh()", Ajax.Interval);
	}

	this.OnTimeout = function() {
		xmlhttp.abort();
		this.Feedback('<font color=red>Timed Out...</font>');
	}

	this.ChipmunkResponse = function() {
		
		if(xmlhttp.readyState == 4) {
			
			window.clearTimeout(timeoutID);
			if (xmlhttp.status==200) {
				if(polling != null) 
					Ajax.Feedback("<font color=green>Connected...</font>");
				Ajax.Status(xmlhttp.responseText);
				
				// No response for longer time
				var now = new Date();
				if(xmlhttp.responseText == "" && document.getElementById('timelimit').value < now.getTime()) {
					window.clearTimeout(polling);
					polling = setTimeout("Ajax.Refresh()", Ajax.LongInterval);
				}
				
				if(xmlhttp.responseText != "") {
					document.getElementById('timelimit').value = now.getTime()+Ajax.DoBreak;
				}
				//alert(xmlhttp.responseText);
			} else {
				Ajax.Feedback("<font color=red>Connection Lost...</font>");
			}
		}
	}

	this.CallInProgress = function(xmlhttp) {
		if(xmlhttp) {
			switch (xmlhttp.readyState) {
				case 1:
				case 2:
				case 3:	return true;
				default: return false;
			}
		} else {
			return false;
		}
	}

	this.Feedback = function(feedback) {}

	this.Status = function(status) {}	

	this.Replace = function(str, old, repl) {
		while((pos = str.indexOf(old)) > -1) {
			str = str.substr(0, pos) + repl + str.substr(pos + old.length);
		} 
		return str;
	}
}
var Ajax;
```


----------



## falco2402 (21. Mai 2008)

deb_ugger hat gesagt.:


> Ich hab diesbezüglich ein paar interessante Seiten gefunden und jetzt mal ein Script geschrieben, das pollt und auf eine php-Seite zugreift.



Echt klasse Arbeit, vielen Dank ! ^^

EDIT// Hab das gleich mal umgesetzt und bin dabei auf ein Problem gestoßen.
Meine server.php sieht so aus:


```
<?
require("../../../inc/mysql_con.php");

$result = mysql_query("SELECT * FROM com_chat_chatnachrichten WHERE (An = '".$_SESSION["akt_chat"]."') order by Zeit DESC;");
$bgcolor[0] = "#9C9C9C";
$bgcolor[1] = "#7F7F77";
while($dataset = mysql_fetch_array($result))
{
$time = explode(",",$dataset['Zeit']);
if($set_color == "1"){$set_color = "0";}else{$set_color = "1";}
$zeilenfarbe = $bgcolor[$set_color];
echo "
<table bgcolor='$zeilenfarbe'>
<tr>
<td width='80'>".$time[1]."</td>
<td width='110'>".$dataset['Von']."</td>
<td width='310'>".$dataset['Nachricht']."</td>
</tr>
</table>";
}
?>
```

Jetzt wollte ich das so machen, dass man mit mehreren Personen gleichzeitig chatten kann und in der $_SESSION["akt_chat"] wird die Id der Personen gespeichert, mit der man aktuell chattet. Das Problem ist nun, dass die Variable nicht an die server.php übergeben wird. Wenn ich sie außerhalb des Skriptes ausgebe, wird mir der Inhalt angezeigt. Jemand eine Idee ?
Achso, noch was, das WHERE ist deshalb, da alle Chatgespräche in der selben Tabelle gespeichert werden und nur die Datensätze angezeigt werden sollen die zu dem aktuell geöffneten Chat gehören.

Gruß und vielen Dank

EDIT// Hmm... hab mal Google bemüht.. kann so anscheinend eh nicht klappen...
EDIT// Okay hat sich erledigt ^^ übergebe dir Variable jetzt per GET an die server.php

```
Ajax.URL = "com/Chat/inc/server.php?an=<?php echo $_SESSION["akt_chat"] ?>";
```


----------

