Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations IamaSherpa on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Creating a chatroom - How to display typed text. 3

Status
Not open for further replies.

casabella

Programmer
Aug 30, 2007
59
US
If you were writing a chatroom, how do you show text typed by others users in one's screen?

Regards,


Jose
 
something like in a table or a floated div with name and post-time on the left and the post on the right.

if that is not what you mean, then please be clearer in your question.
 
You're right, the way I phrased my question it barely deserves an answer.

In a chat room you may have any number of chatters. How do I work it so that the messages from each chatter is displayed on everyone's screens?

I am thinking of a daemon type of process that checks for entries plugged in a text file or MySQL and refreshes the screen but how is such thing written? I don't even know that PHP has the means of writing a 'daemon' like script. I do know that a chat room is possible in PHP I just don't even know where to begin.

Regards,


Jose


 
ok, that makes sense.

there are three basic approaches here (outside of using flash or other downloadable browser helper)

1. display the chat in an iframe and have the iframe meta-refresh every, say, 5 seconds. have the user chat form outside the iframe.
2. display the chat in a div and the chat form in a separate div. have some ajax interaction check the server for updates every few seconds and update the display div.
3. refresh the whole page every few seconds except when the user is typing in his chat box (use js to disable the refresh).

my preference is for item 2. if you're interested I'll knock up a prototype and shove it on a site with the sourcecode - it's only 10 minutes work or so.
 
10 minutes? I have spent several days looking around for ideas and solutions. :(

In sourceforge.net I found a couple of PHP chats but they are written in German (well, most of their messages, comments, prompts ...) and that makes it kind of hard to, say, translate.

I also found the vooodo chat but it requires compiling a C++ daemon and/or using Perl (don't have pearl but about to look it up).

If you could and it is not too much to ask, I will love to see what you're talking about. I am reading a book on AJAX (and PHP) but I am not sharp enough in either to know exactly what to do without doing some intensive homework.

Regards,


Jose
 
Hi

Jose said:
10 minutes?
If you not like the 10 minutes, there is one more way. Certainly not 10 minutes.

4. Use server-push. The CGI script not lets the connection to close and sends each new message immediately as it arrives. This provides the best user experience, but not always works through proxies. Usually is doubled with a client-pull alternative.

Feherke.
 
sorry - got a bit waylaid with real work.

a chat server has been put live at

it's very crude but can be made neater with some decent css.

if i have misunderstood what you mean by a chatroom, let me know. threaded conversations are, to my mind, more like a forum than a chatroom but they are possible with this kind of construct too.

source code is to be found here
i've used pdo and sqlite as I did not want to clog up my mysql installation with such a temporary project. it's (obviously) straightforward to port to mysql (in fact just change the dsn is the absolutely easiest way of doing this
 
That is very cool jpadie!

It shows that things can be accomplished without overly complicating your life. It looks very simple and I bet even I will be able to read through the code and understand it.

Again, thank you so very much !!!!


Jose
 
no worries.

i'll post the code here as well as I may not keep the test site up forever. there is a js file, a php file and an html file.

NB this is far from bullet proof and was put up as a proof of concept only.

Code:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "[URL unfurl="true"]http://www.w3.org/TR/html4/strict.dtd">[/URL]
<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
		<script src="chatRoomServer.js"></script>
		<title>Chat Room</title>
	</head>
	<body>
		<div id="chatForm">
			
				Your Name: <input type="text" name="chatPerson" id="chatPerson"/><br/>
				Your chat: <textarea name="chatText" id="chatText"></textarea><br/>
				<input type="button" name="submit" value="Chat" onclick="sendChat();"/>
		
		</div>
		<div id="chatDiv">
			<table id="chatTable" border="1">
				
			</table>
		</div>
	</body>
</html>

Code:
var timer = null;
var chatTable;
var timestamp = null;
var xo = null;
var url = 'chatRoomServer.php5';

function createObject(){
	var browser = navigator.appName;
    if(browser == "Microsoft Internet Explorer"){
        xo = new ActiveXObject("Microsoft.XMLHTTP");
    }else{
        xo = new XMLHttpRequest();
    }
	
}
function updateChatRoom(){
	if (!xo) {createObject();}
	xo.onreadystatechange = function () {
			if (xo.readyState == 4) {
				if (xo.status == 200) {
					if(xo.responseText == 'none'){
						//do nothing
					} else {
						var rObj = eval('(' + xo.responseText + ')');
						timestamp = rObj.timestamp;
						//console.log('timestamp is '+ timestamp);
						displayUpdatedChats(rObj.chatText)
					}
				}
			}
		};
	try {
		xo.open("POST",url, true);
		} catch (e) {	
		console.log('problem in open command') ;
	}
	try {
		xo.setRequestHeader("Content-type", "application/x-[URL unfurl="true"]www-form-urlencoded");[/URL]
		xo.send('action=getChatData&timestamp='+timestamp);
	} catch (E) {
		console.log('problem retrieving new chats');
	}
}
function displayUpdatedChats(txt){
	chatTable.innerHTML = txt + chatTable.innerHTML;
}

function sendChat(){
	var cP = document.getElementById('chatPerson');
	var cT = document.getElementById('chatText');
	var chatPerson = cP.value;
	var chatText =  cT.value;
	var data = "action=writeChatData&chatPerson="+chatPerson+"&chatText="+chatText;
	if (!xo) {createObject();}
	xo.onreadystatechange = function () {
			if (xo.readyState == 4) {
				if (xo.status == 200) {
					if(xo.responseText == '0'){
						console.log ('problem saving chat data');
					} else {
						//cP.value = '';
						cT.value = '';
					}
				}
			}
		};
	try {
		xo.open("POST", url, true);
		} catch (e) {	
		console.log('problem in open command') ;
	}
	try {
		xo.setRequestHeader("Content-type", "application/x-[URL unfurl="true"]www-form-urlencoded");[/URL]
		xo.send(data);
	} catch (E) {
		console.log('problem sending data');
	}
	return false;
}
window.onload = function(){
	chatTable = document.getElementById('chatTable');
	timer = setInterval(updateChatRoom, 5000);
};

Code:
<?php
$chat = new chats;
class chats{
	private $pdo = null;
	private $timestamp = 0;
	private $action;
	private $db = 'chatDB4.sqlite';
	
	function chats(){
		$this->timestamp = time();
		if (!file_exists($this->db)){
			$this->pdo = new PDO ("sql
			ite:" . $this->db);
			$this->createDatabaseSchema();
		} else {
			$this->pdo = new PDO ('sqlite:'.$this->db);	
		}
		$this->action = isset($_POST['action']) ? $_POST['action'] : 'getChatData';
		$this->switchBoard();
	}
	
	function switchBoard(){
		switch ($this->action){
			case 'writeChatData':
				if ($this->writeChatData()){
					echo '1';
				} else {
					echo '0';
;				}
			break;
			default:
				echo $this->getChatData();
		}	
	}
	
	function getChatData(){
		$return ='';
		$timestamp = isset($_POST['timestamp']) ? $_POST['timestamp'] : 0;
		if ($timestamp == 'null') $timestamp = 0;
		$query = "Select chatID, chatPerson, chatTimestamp, chatText from chat where chatTimestamp > ? order by chatTimestamp DESC limit 50 ";
		$stmnt = $this->pdo->prepare($query);
		$stmnt->execute(array($timestamp));
		$chats = $stmnt->fetchAll();
		foreach ($chats as $chat){
			$date = date('Y-m-d H:i:s', $chat['chatTimestamp']);
			$chatText = nl2br($chat['chatText']);
			$return .= <<<HTML
<tr>
	<td id="{$chat['chatID']}">{$chat['chatPerson']}<br/>$date</td>
	<td>{$chatText}</td>
</tr>
HTML;
		}
		if (empty($return)){
			return 'none';
		} else {
			return json_encode(array('timestamp'=>$this->timestamp,'chatText'=>$return));
		}
	}
	
	function writeChatData(){
		$chatPerson = empty($_POST['chatPerson']) ? NULL : trim($_POST['chatPerson']);
		$chatText = empty($_POST['chatText']) ? NULL : trim($_POST['chatText']);
		if (empty($chatText) || empty($chatPerson)){
			return false;
		} else {
			if (get_magic_quotes_gpc()){
				$chatPerson = stripslashes($chatPerson);
				$chatText = stripslashes($chatText);
			}
			$query = "Insert into chat (chatTimestamp, chatPerson, chatText) values (?,?,?)";
			$stmnt = $this->pdo->prepare($query);
			if ($stmnt){
				$stmnt->execute(array(time(), $chatPerson, $chatText));
			} else {
				print_r($this->pdo->errorInfo());
			}
			if ($stmnt !== false){
				return true;
			} else {
				return false;
			}
		}
	}
	
	function createDatabaseSchema(){
		$query = "	create table 
					chat
					(
					chatID integer NOT NULL PRIMARY KEY AUTOINCREMENT,
					chatTimestamp integer NOT NULL,
					chatPerson text NOT NULL,
					chatText varchar NOT NULL
					)";
		$this->pdo->exec($query);
	}
}
?>
 
jpadie,

I have made a few changes to dress it up a bit. I then moved on to change the database info. I changed:

Code:
From
	private $db = 'chatDB4.sqlite';
To
	private $db = 'mychat';


function chats(){
 $this->timestamp = time();
 if (!file_exists($this->db)){

FROM
  // $this->pdo = new PDO ("sqlite:" . $this->db);

TO
  $this->pdo = new PDO ('mysql:host=localhost;dbname=mychat', $user, $pass);

  $this->createDatabaseSchema();
  } else {


FROM
  // $this->pdo = new PDO ('sqlite:'.$this->db);

TO
  $this->pdo = new PDO ('mysql:host=localhost;dbname=mychat', $user, $pass);
  }

  $this->action = isset($_POST['action']) ? $_POST['action'] : 'getChatData';
  $this->switchBoard();
}

I am afraid I broke the code. I am getting an error which is pointing to the JS script
Code:
function updateChatRoom(){
    if (!xo) {createObject();}
    xo.onreadystatechange = function () {
            if (xo.readyState == 4) {
                if (xo.status == 200) {
                    if(xo.responseText == 'none'){
                        //do nothing
                    } else {
                        var rObj = eval('(' + xo.responseText + ')');
                        timestamp = rObj.timestamp;
^^^^^^^^^^^^^^^^^^THIS LINE^^^^^^^^^^^^^^^^^^^^^^^^

The error message reads:
[message]

Error: missing ) in parenthetical
Source File: Line: 28, Column: 9
Source Code:
<b>Fatal error</b>: Uncaught exception 'PDOException' with message 'could not find driver' in C:\vhosts\fpgroups.com\chatroom\chatRoomServer.php:20

[/message]

Line 20 in chatRoomServer.php reads
Code:
$this->pdo = new PDO ('mysql:host=localhost;dbname=mychat', $user, $pass);

What am I missing? I am using the PDO syntax as shown in php.net.

Thanks,


Jose
 
Uncaught exception 'PDOException' with message 'could not find driver' in C:\vhosts\fpgroups.com\chatroom\chatRoomServer.php:20

that's the problem. the code is not broken but you don't have the mysql driver for PDO installed. if you have root access you can do this with pear/pecl. you also need to enable the extension in php.ini.
 
jpadie,

I have made a great deal of progress. Not as fast as I am sure you would have but I'm happy thus far.

feherke gave me a great JS command I needed to scroll my iframe (this is where I now show the chat text) to the very bottom thus giving the visual of newly entered text scroll from bottom up ...

So far the only error I am getting is

Code:
Error: [Exception... "Component returned failure code: 0x80040111 (NS_ERROR_NOT_AVAILABLE) [nsIXMLHttpRequest.status]"  nsresult: "0x80040111 (NS_ERROR_NOT_AVAILABLE)"  location: "JS frame :: [URL unfurl="true"]http://www.fpgroups.com/chatroom/loadChatText.js[/URL] :: anonymous :: line 22"  data: no]
Source File: [URL unfurl="true"]http://www.fpgroups.com/chatroom/loadChatText.js[/URL]
Line: 22

Which points to

Code:
function updateChatRoom(){
    if (!xo) {createObject();}
    xo.onreadystatechange = function () {
            if (xo.readyState == 4) {

vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
                if (xo.status == 200) {
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

                    if(xo.responseText == 'none'){
                        //do nothing
                    } else {
                        var rObj = eval('(' + xo.responseText + ')');
                        timestamp = rObj.timestamp;
                        //console.log('timestamp is '+ timestamp);
                        displayUpdatedChats(rObj.chatText);
                    }
                }
            }
        };

What do you think this is and what must I do to fix it?

Oh, check out the chat



Regards,


Jose
 
personally, i think that the error can be safely ignored. but you could always remove the conditionality of the status checking. the really important test is the readystate.
 
why an iframe? to me, there's very little point in having ajax interaction with an iframe. you could just use a meta-refresh with feherke's scroller.
 
I thought of the iframe so that chatters have the option to scroll back through the history of posted messages.

Other than that, no other reason.

Thanks for taking the time to respond. I truly appreciate your input and advise!

Regards,


Jose
 
you don't need an iframe for that. just a div that's scrollable. give the div a fixed height and set the overflow property to auto.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top