首先看我们的目录结构:
chat.html
sub.php
pub.php
redis.php

chat.html是访问的web页面,进行聊天室的操作
redis.php调用redis服务
sub是订阅功能
pub是发布功能

下面看代码

chat.html:

<meta charset="utf8">
<div style="width:300px;height:300px;margin:0 auto;border:1px solid #ccc"></div>
<center>
    <textarea style="width:300px;height:100px"></textarea><br/>
    <button>发送</button>
</center>
<script src="http://code.jquery.com/jquery-1.11.2.min.js"></script>
<script>
    $("button").click(function(){
        var text = $("textarea").val();
        $.post("pub.php",{"content":text});
    });

    function getdata(){
        $.post("sub.php",function(data){
            if(data){
                $("div").append(data+"<br/>");
                $("textarea").val("");
                getdata();
            }
        });
    }
    getdata();
</script>

redis.php:

<?php
    header("content-type:text/html;charset=utf-8");
    
    ini_set('default_socket_timeout',-1);
    
    $redis = new Redis();
    $redis -> pconnect('localhost',6379);

pub.php:

<?php
include './redis.php';

$redis -> publish('tv1',$_POST['content']);

sub.php:

<?php
include './redis.php';

$redis -> subscribe(array('tv1'),'callback');

function callback($redis,$channel,$contect){
    echo $channel;
    echo ":";
    echo $contect;
    echo "<br/>";
    exit();
}

解释下代码:
1.html中点击发送的事件,在pub.php中会将数据发布到redis中。
2.html中默认走的sub,是sub获取redis频道中的值,处于监听状态,频道中的值不发生改变,则一直处于监听状态,当值发生了改变,sub得到返回值,返回给页面,html中js将数据打到页面上,然后重新进行一波sub,继续监听。

原理:
似乎也没啥好讲的,主要是redis的发布/订阅功能,会有一个阻塞的作用,形成一个long poll可以达到类似websocket的效果,不过性能是受配合的语言(php)影响的。

代码git: https://git.coding.net/jhcloud/redis_chat.git