librelist archives

« back to archive

Real time chat server in 30 lines of PHP code

Real time chat server in 30 lines of PHP code

From:
Loic d'Anterroches
Date:
2011-02-22 @ 08:41
Hello,

Can you create a realtime jsSocket based chat server with your PHP
framework in 30 lines of code? If you are using Photon, yes, of course:

namespace photonchat\views;

use \photon\shortcuts;

class Chat
{
    /**
     * Just serving the main HTML of the chat window, it could done
     * directly by Mongrel2.
     */
    public function home($request, $match)
    {
        return shortcuts\Template::RenderToResponse('photonchat/home.html',
                                                    array(),
                                                    $request);
    }

    /**
     * Here we serve the request coming from the chat socket.
     */
    public function chatbox($request, $match)
    {
        static $user_list = array();
        $data = $request->BODY;
        if ('join' === $request->BODY->type) {
            $request->conn->deliver($request->mess->sender,
                                    array_keys($user_list),
                                    json_encode($request->BODY));
            $user_list[$request->mess->conn_id] = $request->BODY->user;
            $res = array('type' => 'userList',
                         'users' => array_values($user_list));
            print "JOIN ". $request->mess->conn_id . "\n";
            return new \photon\http\response\Json($res);
        } elseif ('disconnect' === $request->BODY->type) {
            print "DISCONNECTED ". $request->mess->conn_id . "\n";

            if (isset($user_list[$request->mess->conn_id])) {
                $data->user = $user_list[$request->mess->conn_id];
                unset($user_list[$request->mess->conn_id]);
            }
            $request->conn->deliver($request->mess->sender,
                                    array_keys($user_list),
                                    json_encode($data));
        } elseif (!isset($user_list[$request->mess->conn_id])) {
            $user_list[$data->user] = $request->mess->conn_id;
            print "AUTO JOIN ". $request->mess->conn_id . "\n";
        } elseif ('msg' === $data->type) {
            $request->conn->deliver($request->mess->sender,
                                    array_keys($user_list),
                                    json_encode($data));
            print "MESS FROM ". $request->mess->conn_id . "\n";
        }
        return false; // By default, say nothing
    }
}


The mongrel2 configuration:

handler_test = Handler(send_spec='tcp://127.0.0.1:9997',
                       send_ident='34f9ceee-cd52-4b7f-b197-88bf2f0ec378',
                       recv_spec='tcp://127.0.0.1:9996', recv_ident='')

main = Server(
    uuid="f400bf85-4538-4f7a-8908-67e313d515c2",
    access_log="/logs/access.log",
    error_log="/logs/error.log",
    default_host="localhost",
    chroot="./",
    name="test",
    pid_file="/run/mongrel2.pid",
    port=6767,
    hosts = [
        Host(name="localhost", routes={
            '/tests/': Dir(base='tests/', index_file='index.html',
                             default_ctype='text/plain'),
            '/handlertest': handler_test,
            '@photonchat': handler_test
        })
    ]
)
settings = { "limits.content_length": 2097152000,
	     "upload.temp_store": "/tmp/mongrel2.upload.XXXXXX" }
servers = [main]

You can see the @photonchat which informs that the jsSocket calls will
be handled by the Photon handler. The UI side is copied/pasted from the
Mongrel2 chat example.

The result:

http://xhtml.net/php/pluf-framework-php/650-Un-serveur-de-chat-temps-reel-en-PHP-en-30-lines-de-code-avec-Photon

Enjoy :)
loïc


-- 
Dr Loïc d'Anterroches
Founder Céondo Ltd

w: www.ceondo.com       |  e: loic@ceondo.com
t: +44 (0)207 183 0016  |  f: +44 (0)207 183 0124

Céondo Ltd
Dalton House
60 Windsor Avenue
London
SW19 2RR / United Kingdom