Ir para conteúdo

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

BigJhow

Chat em AJAX, PHP, IRC, MySQL....

Recommended Posts

Eu, até bem pouco tempo, usava um servidor IRCx apoiando salas de chat com o ActiveX MSN Chat Control. Devido às incompatibilidades com os navegadores que não usam como base o Internet Explorer, e também ao abandono do desenvolvimento do controle por parte da Microsoft, venho procurando novas alternativas quanto a chats.

 

Vinha até bem pouco tempo elaborando um sistema PHP + MySQL + AJAX, mas me preocupo com as requisições ao servidor, e com as consultas MySQL, que podem não ter o desempenho esperado.

 

É possível usar o protocolo IRC como servidor de mensagens, ao invés do MySQL, com melhora de desempenho? Como minimizar ao máximo o número de requisições ao servidor, sem comprometer o ping do chat?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Amigo, primeiro vamos esquecer o protocolo que é apenas um conjunto de regras para o envio e recebimento de mensagens.

 

 

A arquitetura de um sistema de chat é a seguinte:

 

Imagem Postada

 

Como pode ver, temos 2 tipos de participante:

 

1. Mediator - Esse é o cara que será responsável por despachar as mensagens para os participantes do chat.

2. Colleague - Cada Colleague comunicará exclusivamente com seu Mediator, ou seja, nenhum Colleague comunica-se diretamente com outro Colleague, eles mandam as mensagens para o Mediator e esse se encarregará de despachar a mensagem para os outros participantes.

 

Ficaria assim:

 

Imagem Postada

De forma geral, a implementação seria a seguinte:

 

Message.php

<?php
class Message {
private $text;
private $utm;

public function __construct( $message ){
	$this->text = $message;
	$this->utm = time();
}


public function getText(){
	return $this->text;
}

public function getTime(){
	return $this->utm;
}
}

 

Colleague.php

<?php
interface Colleague {
public function getName();
public function receiveMessage( Message $message , Colleague $from );
public function sendMessage( $message );
}

 

Mediator.php

<?php
interface Mediator {
public function createColleague( $name );
public function sendMessage( Colleague $from , Message $message );
}

 

Participant.php

<?php
class Participant implements Colleague {
private $mediator;
private $name;

public function __construct( $name , Mediator $mediator ){
	$this->name = $name;
	$this->mediator = $mediator;
}

public function getName(){
	return $this->name;
}

public function receiveMessage( Message $message , Colleague $from ){
	printf( "[%s] %s para %s: %s\n" , strftime( '%H:%M:%S' , $message->getTime() ) , $from->getName() , $this->name , $message->getText() );
}

public function sendMessage( $message ){
	$this->mediator->sendMessage( $this , new Message( $message ) );
}
}

 

ChatRoom.php

<?php
class ChatRoom implements Mediator {
private $colleagues;

public function __construct(){
	$this->colleagues = new ArrayObject();
}

public function createColleague( $name ){
	$colleague = new Participant( $name , $this );
	$this->colleagues->append( $colleague );

	return $colleague;
}

public function sendMessage( Colleague $from , Message $message ){
	$iterator = $this->colleagues->getIterator();

	for ( $iterator->rewind() ; $iterator->valid() ; $iterator->next() ){
		$colleague = $iterator->current();

		if ( $colleague !== $from ){
			$colleague->receiveMessage( $message , $from );
		}
	}
}
}

 

Usando isso ai:

<?php
$chat = new ChatRoom();

$fulano = $chat->createColleague( 'Fulano' );
$beltrano = $chat->createColleague( 'Beltrano' );
$cicrano = $chat->createColleague( 'Cicrano' );

$fulano->sendMessage( 'Olá !!!' );
$cicrano->sendMessage( 'Olá, e ai ?' );

 

A saída será:

[09:25:47] Fulano para Beltrano: Olá !!!

[09:25:47] Fulano para Cicrano: Olá !!!

[09:25:47] Cicrano para Fulano: Olá, e ai ?

[09:25:47] Cicrano para Beltrano: Olá, e ai ?

 

Como pode perceber, a implementação da forma geral é bem simples afinal, estamos trabalhando na mesma camada. O problema começa quando temos duas ou mais camadas, que é justamente o caso, onde o Mediator estará em um servidor e cada Colleague no seu respectivo browser.

 

Se seu Mediator for um servidor baseado em sockets, você pode ter do lado do cliente um Observer que atuará como um ChangeManager, ou seja, sempre que o Mediator fizer uma notificação, seu Colleague saberá.

 

Como, para sair do chat, um Colleague notificará seu Mediator, você não precisa de "pings" e a responsabilidade de notificar os outros Colleagues sobre a saída, ou mesmo sobre a ausência, de um Colleague é apenas do Mediator.

 

Como isso você elimina completamente os "pings", tem a dinamicidade necessária para um sistema de chat e pode implementar qualquer protocolo que desejar, seja IRC, XMPP ou qualquer outro.

 

;)

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Segundo seu tutorial, estou usando o MySQL como 'Mediator'. Mas, eu paro num problema: como o MySQL irá enviar uma notificação ao PHP, sem que este fique fazendo requisições involuntárias (para não pesar no servidor)? O uso de sockets (como o servidor IRC) alivia o MySQL, mas não resolve o problema tráfego =/

Compartilhar este post


Link para o post
Compartilhar em outros sites

Segundo seu tutorial, estou usando o MySQL como 'Mediator'. Mas, eu paro num problema: como o MySQL irá enviar uma notificação ao PHP, sem que este fique fazendo requisições involuntárias (para não pesar no servidor)? O uso de sockets (como o servidor IRC) alivia o MySQL, mas não resolve o problema tráfego =/

 

Opz....

 

O MySQL (nem nenhum sistema de armazenamento) será seu mediator.

 

O Mediator pode até gravar informações no banco, mas o Mediator não é o banco.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Opa, então eu entendi errado!

 

Supondo que exista um arquivo responsável pela exibição de mensagens. Ele seria o Mediator? Ou o mediator seria algo que disesse quando aparecesse novas mensagens no banco de dados (acho que a última é a correta).

Compartilhar este post


Link para o post
Compartilhar em outros sites

Opa, então eu entendi errado!

 

Sim,

 

Você não apenas compreendeu errado como está muito preocupado com a implementação, esqueça ela, não é importante; Foque na arquitetura, esqueça protocolos, sistemas de armazenamento, exibição e qualquer coisa que não esteja relacionado com arquitetura...

 

Quando se foca na implementação, esquece-se da solução.

 

Pense que você terá dois participantes: o Mediator, que será responsável por receber e despachar as mensagens dos/para os Colleagues e os Colleagues, que serão os usuários do chat e que enviarão mensagens exclusivamente para seu Mediator.

 

O Mediator estará no servidor, pode-se usar qualquer protocolo para enviar a mensagem, pode-se utilizar qualquer sistema de armazenamento ou absolutamente nenhum armazenamento, isso é indiferente, o Mediator apenas receberá as mensagens e terá a responsabilidade de despachá-las para os outros Colleagues, se ele vai gravar as mensagens em um banco de dados não é importante.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Hm, captei, e já implementei isso aqui xP vlw o/ Agora o chat funciona \o/

 

Ok, está tudo funcionando perfeitamente Mas continuo preocupado com o quanto o sistema pode pesar no servidor. As requisições estão sendo feitas via AJAX (4 divs sendo atualizadas)

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.