zoukankan      html  css  js  c++  java
  • 在面试时用php+swoole编写了一个简易聊天室,面试官让我明天来上班!

    Swoole:面向生产环境的 PHP 异步网络通信引擎

    使 PHP 开发人员可以编写高性能的异步并发 TCP、UDP、Unix Socket、HTTP,WebSocket 服务。Swoole 可以广泛应用于互联网、移动通信、企业软件、云计算、网络游戏、物联网(IOT)、车联网、智能家居等领域。使用 PHP + Swoole 作为网络通信框架,可以使企业 IT 研发团队的效率大大提升,更加专注于开发创新产品。

    新建PushServer.php

    <?php
    /**
     * Created by PhpStorm.
     * User: zhengbingdong
     * Date: 2020/08/15
     * Time: 01:06
     */
    
    class PushServer
    {
        private static $instance;
        private static $server;
        public $messageHandler;//处理消息的对象
    
        //不能够在类外面创建该对象的实例
        private function __construct()
    {
            //>>1.创建websocket对象
            self::$server = new swoole_websocket_server('0.0.0.0', 9502);
            //>>2.注册事件
            self::$server->on('open', [$this, 'onOpen']);//将当前类的onOpen方法作为open的事件处理函数
            self::$server->on('message', [$this, 'onMessage']);
            self::$server->on('close', [$this, 'onClose']);
            self::$server->on('workerStart',[$this,'onWorkerStart']);
        }
    
        //当客户端连上之后要执行的方法
        public function onOpen($server, $req)
    {
            echo "connection open: {$req->fd}
    ";
        }
    
        //客户端向服务器发送消息要执行的方法
        public function onMessage($server, $frame)
    {
            //将传输的json转成数组
            $data = json_decode($frame->data,true);
            //检查方法是否存在
            if (method_exists($this->messageHandler,$data['cmd'])){
                call_user_func([$this->messageHandler,$data['cmd']],self::$server,$data['data']);
            }else{
                $outMessage = json_encode([
                    'status' => 'error',
                    'msg' => '非法操作'
                ]);
                echo $outMessage."
    ";
                self::$server->push($frame->fd, $outMessage);
            }
        }
    
        //客户端和服务器端断开连接时执行的方法
        public function onClose($server,$fd)
    {
            $online = [];
            foreach ($server->connections as $clientId) {
                array_push($online, $clientId);
                $outMessage = json_encode(
                    [
                        'type' => 'close',
                        'fid' => $clientId,
                        'online' => $online,
                        'num' => count($server->connections)
                    ]
                );
                self::$server->push($clientId, $outMessage);
            }
            echo "当前服务器共有 " . count($server->connections) . " 个连接
    ";
            echo '客户端或服务器断开连接'.$fd."
    ";
        }
    
        //服务器启动之后执行
        public function onWorkerStart(){
            echo 'onWorkerStart----------'.date('Y-m-d H:i:s')."
    ";
            require './MessageHandler.php';
            $this->messageHandler = new MessageHandler();
        }
    
        public static function getInstance()
    {
            if (!self::$instance instanceof self) {
                self::$instance = new self();
            }
            return self::$instance;
        }
    
        public function start()
    {
            self::$server->start();
        }
    }
    
    PushServer::getInstance()->start();//启动推送服务器
    

    新建MessageHandler.php

    <?php
    /**
     * Created by PhpStorm.
     * User: zhengbingdong
     * Date: 2020/08/15
     * Time: 01:06
     */
    
    class MessageHandler
    {
        public function join($server, $data)
    {
            foreach ($server->connections as $fd) {
                $outMessage = json_encode(
                    [
                        'type' => 'join',
                        'client_id' => $fd,
                        'name' => $data['name'],
                        'num' => count($server->connections)
                    ]
                );
                $server->push($fd, $outMessage);
            }
        }
    
        public function sendMessage($server, $data){
            foreach ($server->connections as $fd) {
                $outMessage = json_encode(
                    [
                        'name' => $data['name'],
                        'content' => $data['content']
                    ]
                );
                $server->push($fd, $outMessage);
            }
        }
    
        public function changeNickName($server, $data){
            foreach ($server->connections as $fd) {
                $outMessage = json_encode(
                    [
                        'type' => 'changeNickName',
                        'before' => $data['before'],
                        'after' => $data['after']
                    ]
                );
                $server->push($fd, $outMessage);
            }
        }
    
        public function outLine(){
            echo '-------------------------离开了';
        }
    }
    

    新建聊天室页面

    <!DOCTYPE html>
    <html xmlns="http://www.w3.org/1999/xhtml">
    
        <head>
            <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
            <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
            <title>匿名即时聊天室</title>
            <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
        </head>
        <style type="text/css" media="all">
        body {
            padding: 0;
            margin: 0;
        }
        #online {
             100%;
            margin: 0 auto;
        }
        #messgae {
            background: #eee;
            padding: 5px;
            margin-bottom: 15px;
            height: 380px;
            overflow: scroll;
        }
        #online-num {
            font-size: 15px;
            padding-left: 10px;
        }
        #socket {
            background: #f5f5f5;
            padding: 20px;
        }
        #name {
             98%;
        }
        #content {
             98%;
        }
        #sender {
             100%;
        }
    </style>
    
        <body>
            <div id="online">
                <div id="messgae">
                     <h3 id="title">匿名聊天室<span id="online-num">当前在线<span id="num"></span>人</span></h3>
    
                </div>
                <div id="socket">
                    <p>网名:
                        <input type="text" id="name" value="">
                    </p>
                    <p>内容:
                        <textarea name="" id="content" rows="8" cols="40"></textarea>
                    </p>
                    <p>
                        <input type="submit" name="" id="sender" value="发送" />
                    </p>
                </div>
            </div>
            <script>
            var cookie = {
                set: function (key, val, time) { //设置cookie方法
                    var date = new Date(); //获取当前时间
                    var expiresDays = time; //将date设置为n天以后的时间
                    date.setTime(date.getTime() + expiresDays * 24 * 3600 * 1000); //格式化为cookie识别的时间
                    document.cookie = key + "=" + val + ";expires=" + date.toGMTString(); //设置cookie
                },
                get: function (key) { //获取cookie方法
                    /*获取cookie参数*/
                    var getCookie = document.cookie.replace(/[ ]/g, ""); //获取cookie,并且将获得的cookie格式化,去掉空格字符
                    var arrCookie = getCookie.split(";") //将获得的cookie以"分号"为标识 将cookie保存到arrCookie的数组中
                    var tips; //声明变量tips
                    for (var i = 0; i < arrCookie.length; i++) { //使用for循环查找cookie中的tips变量
                        var arr = arrCookie[i].split("="); //将单条cookie用"等号"为标识,将单条cookie保存为arr数组
                        if (key == arr[0]) { //匹配变量名称,其中arr[0]是指的cookie名称,如果该条变量为tips则执行判断语句中的赋值操作
                            tips = arr[1]; //将cookie的值赋给变量tips
                            break; //终止for循环遍历
                        }
                    }
                    return tips;
                },
                delete: function (key) { //删除cookie方法
                    var date = new Date(); //获取当前时间
                    date.setTime(date.getTime() - 10000); //将date设置为过去的时间
                    document.cookie = key + "=v; expires =" + date.toGMTString(); //设置cookie
                }
            };
            $(function () {
                $('#name').val(cookie.get("userNickname") ? cookie.get("userNickname"):'游客' + <?= date('YmdHis'); ?>)
                $('#name').blur(function () {
                    var name = $('#name').val();
                    var before = cookie.get("userNickname") ? cookie.get("userNickname") : name;
                    cookie.set("userNickname", name, 24)
                    websocket.send('{"cmd":"changeNickName","data":{"before":"' + before + '","after":"' + name + '"}}');
                });
                var websocket = new WebSocket("ws://192.168.31.107:9502");
                websocket.onopen = function () {
                    console.log('连接上服务器');
                    var intNickName = cookie.get("userNickname") ? cookie.get("userNickname") : '游客' + <?= date('YmdHis'); ?> ;
                    cookie.set("userNickname", intNickName, 24);
                    websocket.send('{"cmd":"join","data":{"name":"' + intNickName + '"}}');
                }
                websocket.onmessage = function (event) {
                    var getName = cookie.get("userNickname");
                    var data = JSON.parse(event.data);
                    //console.log(data)
                    if (data.type == 'join') {
                        $('#messgae').append('<p>系统提示:' + data.name + '加入聊天室</p>');
                        $('#num').text(data.num);
                    } else if (data.type == 'close') {
                        $('#messgae').append('<p>系统提示:' + data.fid + '离开了聊天室</p>');
                    } else if (data.type == 'changeNickName') {
                        $('#messgae').append('<p>系统提示:' + data.before + '更改了网名为《' + data.after + '》</p>');
                    } else {
                        $('#messgae').append(
                            '<p>' + data.name + ':' + data.content + '</p>');
                    }
                    goBottom();
                }
                websocket.onclose = function () {
                    console.log('断开了链接');
                }
                $('#sender').click(function () {
                    var name = $('#name').val();
                    var sendContent = $('#content').val()
                    websocket.send('{"cmd":"sendMessage","data":{"name":"' + name + '","content":"' + sendContent + '"}}');
                    $('#content').val('');
                    goBottom();
                })
    
                function goBottom(){
                    var div = document.getElementById('messgae');
                    div.scrollTop = div.scrollHeight;
                }
            });
    </script>
        </body>
    
    </html>
    

    点关注,不迷路

    好了各位,以上就是这篇文章的全部内容了,能看到这里的人呀,都是人才。之前说过,PHP方面的技术点很多,也是因为太多了,实在是写不过来,写过来了大家也不会看的太多,所以我这里把它整理成了PDF和文档,如果有需要的可以

    点击进入暗号: PHP+「平台」

    在这里插入图片描述

    在这里插入图片描述


    更多学习内容可以访问【对标大厂】精品PHP架构师教程目录大全,只要你能看完保证薪资上升一个台阶(持续更新)

    以上内容希望帮助到大家,很多PHPer在进阶的时候总会遇到一些问题和瓶颈,业务代码写多了没有方向感,不知道该从那里入手去提升,对此我整理了一些资料,包括但不限于:分布式架构、高可扩展、高性能、高并发、服务器性能调优、TP6,laravel,YII2,Redis,Swoole、Swoft、Kafka、Mysql优化、shell脚本、Docker、微服务、Nginx等多个知识点高级进阶干货需要的可以免费分享给大家,需要的可以加入我的 PHP技术交流群

  • 相关阅读:
    Java.util.concurrent包学习(一) BlockingQueue接口
    [转载]最牛B的编码套路
    思考人生
    非奇异矩阵的零度互补法则
    Hopfield 网络(下)
    Hopfield 网络(上)
    矩阵的相似性与对角化
    左右特征向量
    特征多项式、代数重数与几何重数
    特征值和特征向量
  • 原文地址:https://www.cnblogs.com/it-abu/p/14194286.html
Copyright © 2011-2022 走看看