zoukankan      html  css  js  c++  java
  • PHP 简易聊天室 利用redis的订阅发布功能

    demo:
    http://139.196.97.20: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>
  • 相关阅读:
    [SAP ABAP开发技术总结]ALV
    [SAP ABAP开发技术总结]逻辑数据库
    [SAP ABAP开发技术总结]OPEN SQL
    [SAP ABAP开发技术总结]内表操作
    [SAP ABAP开发技术总结]面向对象OO
    [SAP ABAP开发技术总结]反射,动态创建内表、结构、变量
    [SAP ABAP开发技术总结]动态语句、动态程序
    [SAP ABAP开发技术总结]数据引用(data references)、对象引用(object references)
    [SAP ABAP开发技术总结]字段符号FIELD-SYMBOLS
    [SAP ABAP开发技术总结]Form(subroutine)、Function参数传值传址
  • 原文地址:https://www.cnblogs.com/lzs-888/p/10382339.html
Copyright © 2011-2022 走看看