PHP 简易聊天室 利用redis的订阅发布功能

demo:
http://www.200ok.fun:8083/api/chat/list

前言:
这个种方式太耗redis连接数,每次订阅都会新起一个进程,仅供练手使用,切勿用于生产环境。

原理:
1.PHP提供两个接口,订阅,发布,redis就有提供
2.订阅接口会卡住,不会马上response,直至有发布的消息
3.前端需要在一次订阅请求成功或失败后立即重新发一个订阅请求,以免错漏信息

后台代码(用的laravel框架,只要能调用redis,实现一致即可):

// 订阅接口
public
function subscribe(Request $request) { Redis::subscribe([self::CHATROOMCHANNEL], function ($message) { echo json_encode($this->rtnSucc($message)); exit; }); }
// 发布接口
public function publish(Request $request) { $num = Redis::publish(self::CHATROOMCHANNEL, $request->input('say', '对方没有说话')); if ($num) { return $this->rtnSucc($num); } else { return $this->rtnErr(100, "发送失败"); } } private function rtnSucc($data) { return ["rtn" => 0, "msg" => "", "data" => $data]; } private function rtnErr($rtn, $msg = "") { return ["rtn" => $rtn, "msg" => $msg, "data" => ""]; }

 

前端代码:

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>200OK ChatRoom</title>
    <style>
        body {
            margin: 0;
            padding: 0;
        }

        #input_box {
            width: 92%;
            height: 100px;
            margin: 0 auto;
            display: block;
            border-radius: 2px;
        }

        #btn {
            height: 30px;
            text-align: center;
            font-size: 16px;
            background-color: #E91E63;
            color: #fff;
            margin: 10px 10px 0 10px;
            border-radius: 2px;
            line-height: 30px;
        }

        #content {
            margin: 0 10px;
            font-size: 16px;
            color: #795548;
        }
    </style>
</head>
<body>

<div id="content">
    <p>200 OK ChatRoom!</p>
</div>
<textarea id="input_box" placeholder="输入你想说的话"></textarea>
<div id="btn">发射!</div>
<script src="/js/zepto.js"></script>
<script src="/js/md5.min.js"></script>
<script>
    // dom
    let $input_box = $("#input_box");
    let $content = $("#content");
    let $btn = $("#btn");
    let myName = getRandomName();

    main();

    // 入口
    function main() {
        bindEvent();
        subscribe();
        $content.append(pp("你叫:" + myName));
    }

    // 监听事件
    function bindEvent() {
        $btn.on("click", function () {
            say();
        });

        $input_box.bind('keyup', function (e) {
            if (13 === e.keyCode) {
                say();
            }
        });
    }

    //
    function say() {
        var str = getC().trim();
        if (!str) {
            error("请输入内容");
            return;
        }
        publish(namePrefix() + str, function (rp) {
            $input_box.val("");
            $input_box.focus();
        });
    }

    // 获取输入框内容
    function getC() {
        return $input_box.val();
    }

    // 订阅 回调之后继续订阅
    function subscribe(callback) {
        $.ajax({
            type: 'GET',
            url: '/api/chat/subscribe',
            data: {},
            dataType: 'json',
            timeout: 10000,
            success: function (data) {
                if (0 === data.rtn) {
                    $content.append(pp(data.data));
                }
                subscribe();
            },
            error: function (xhr, type) {
                // 防止雪崩
                setTimeout(function () {
                    subscribe();
                }, 1000);
            }
        });
    }

    // 发布
    function publish(str, callback) {
        $.get('/api/chat/publish?say=' + str, function (response) {
            callback(response);
        });
    }

    function pp(str) {
        return "<p>" + str + "</p>"
    }

    function namePrefix() {
        return myName + ": ";
    }

    // 错误处理
    function error(str) {
        alert(str);
    }

    // 生成随机姓名
    function getRandomName() {
        var familyNames = new Array(
            "", "", "", "", "", "", "", "", "", "",
            "", "", "", "", "", "", "", "", "", "",
            "", "", "", "", "", "", "", "", "", "",
            "", "", "", "", "", "", "", "", "", "",
            "", "", "", "", "", "", "", "", "", "",
            "", "", "", "", "", "", "", "", "", "",
            "", "", "", "", "", "", "", "", "", "",
            "", "", "", "", "", "", "", "", "", "",
            "", "", "", "", "", "", "", "", "", "",
            "", "", "", "", "", "", "", "", "", ""
        );
        var givenNames = new Array(
            "子璇", "", "国栋", "夫子", "瑞堂", "", "", "", "国贤", "贺祥", "晨涛",
            "昊轩", "易轩", "益辰", "益帆", "益冉", "瑾春", "瑾昆", "春齐", "", "文昊",
            "东东", "雄霖", "浩晨", "熙涵", "溶溶", "冰枫", "欣欣", "宜豪", "欣慧", "建政",
            "美欣", "淑慧", "文轩", "文杰", "欣源", "忠林", "榕润", "欣汝", "慧嘉", "新建",
            "建林", "亦菲", "", "冰洁", "佳欣", "涵涵", "禹辰", "淳美", "泽惠", "伟洋",
            "涵越", "润丽", "", "淑华", "晶莹", "凌晶", "苒溪", "雨涵", "嘉怡", "佳毅",
            "子辰", "佳琪", "紫轩", "瑞辰", "昕蕊", "", "明远", "欣宜", "泽远", "欣怡",
            "佳怡", "佳惠", "晨茜", "晨璐", "运昊", "汝鑫", "淑君", "晶滢", "润莎", "榕汕",
            "佳钰", "佳玉", "晓庆", "一鸣", "语晨", "添池", "添昊", "雨泽", "雅晗", "雅涵",
            "清妍", "诗悦", "嘉乐", "晨涵", "天赫", "玥傲", "佳昊", "天昊", "萌萌", "若萌"
        );

        var i = parseInt(10 * Math.random()) * 10 + parseInt(10 * Math.random());
        var familyName = familyNames[i];

        var j = parseInt(10 * Math.random()) * 10 + parseInt(10 * Math.random());
        var givenName = givenNames[i];

        return familyName + givenName;
    }
</script>
</body>
</html>

 

转载于:https://www.cnblogs.com/lzs-888/p/10382339.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值