• swoole实验版聊天室


      “swoole实验版聊天室”是依据一堂swoole培训课内容改编的,结合了bootstrap前端框架、redis数据库、jquery框架等实现基本功能,只是体现了swoole的应用,并不是为了专门写个聊天室。


      本程序开发环境:
      1.ubuntu16.04.1
      2.PHP Version 7.2.21
      3.swoole Version 4.4.3
      4.Redis Version 4.0.2
      安装步骤(略)。
      效果如下:

    代码如下:

    index.php文件

    <!DOCTYPE html>
    <html>
        <head>
            <title>swoole实验版聊天室</title>
            <meta charset="utf-8">
            <meta name="viewport" content="width=device-width, initial-scale=1">
            <meta http-equiv="cache-control" content="no-cache">
            <link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/4.1.0/css/bootstrap.min.css">
            <script src="https://cdn.staticfile.org/jquery/3.2.1/jquery.min.js"></script>
            <script src="https://cdn.staticfile.org/popper.js/1.12.5/umd/popper.min.js"></script>
            <script src="https://cdn.staticfile.org/twitter-bootstrap/4.1.0/js/bootstrap.min.js"></script>
            <link rel="stylesheet" href="https://cdn.staticfile.org/font-awesome/4.7.0/css/font-awesome.css">
    
            <style>
                body{background-color: #191970;}
                @media screen and (min- 992px) {
                        div{display: none}
                        body {background: #fff}
                        body:before {
                            content: "不支持此设备浏览!";
                            position: absolute;
                            left: 10px;
                            top: 30px
                     }
                 }
                 
                @media screen and (min- 768px) and (max- 991px) {
                        div{display: none}
                        body {background: #fff}
                        body:before {
                            content: "不支持此设备浏览!";
                            position: absolute;
                            left: 10px;
                            top: 30px
                     }
                 }
                 
                @media screen and (min- 576px) and (max- 767px) {
                    #result{
                         100%; 
                        height: 300px; 
                        overflow-y: scroll;
                        margin: 0px;
                        padding: 5px;
                     }
                     #is-open{
                         display: inline-block;
                         border: solid 1px #dcdcdc;
                         padding: 6px;
                         margin: 6px 0px;
                         border-radius: 8px;
                         color: #fff;
                     }
                     .ms {
                         display:inline-block;
                         80%
                     }
                     .msl {
                         display:inline-block;
                         40%;
                         background-color: #66cdaa
                     }
                     .btn {
                         display:inline-block;
                         float: right;
                         20%
                     }
                     .mess{
                         color: #00fa9a;
                         text-align: right
                     }
                     .mess-1{
                         display: inline-block;
                         word-wrap:break-word;
                         word-break:break-all;
                         color: #2f4f4f;
                         background-color:#f4a460;
                         padding: 8px;
                         border-radius: 8px;
                         text-align: left
                     }
                     .mess-1-1, .mess-2-2 {
                          display: inline-block;
                          color: #000;
                          font-weight: bold;
                          background-color: #add8e6;
                      }
                      .mess-1-1{
                          padding: 8px;
                          border-radius: 8px
                      }
                      .mess-2-2{
                          padding: 8px;
                          border-radius: 8px
                      }
                     .mess-2{
                         display: inline-block;
                         word-wrap:break-word;
                         word-break:break-all;
                         color: #696969;
                         background-color:#fff;
                         padding: 8px;
                         border-radius: 8px
                     }
                     .tot{
                         display: inline-block;
                          40%;
                         word-wrap:break-word;
                         word-break:break-all;
                         color: #fff;
                         float: right;
                         margin-top: 3px;
                     }
                     .bottom-box{
                         position: fixed;
                         left: 0px;
                         bottom: 0px;
                         100%;
                         background-color: #191970;
                         padding-top: 10px
                      }
                  }
                  
                @media screen and (min- 300px) and (max- 575px) {
                    #result{
                         100%; 
                        height: 300px; 
                        overflow-y: scroll;
                        margin: 0px;
                        padding: 5px;
                     }
                     #is-open{
                         display: inline-block;
                         border: solid 1px #dcdcdc;
                         padding: 6px;
                         margin: 6px 0px;
                         border-radius: 8px;
                         color: #fff;
                     }
                     .ms {
                         display:inline-block;
                         80%
                     }
                     .msl {
                         display:inline-block;
                         40%;
                         background-color: #66cdaa
                     }
                     .btn {
                         display:inline-block;
                         float: right;
                         20%
                     }
                     .mess{
                         color: #00fa9a;
                         text-align: right
                     }
                     .mess-1{
                         display: inline-block;
                         word-wrap:break-word;
                         word-break:break-all;
                         color: #2f4f4f;
                         background-color:#f4a460;
                         padding: 8px;
                         border-radius: 8px;
                         text-align: left
                     }
                     .mess-1-1, .mess-2-2 {
                          display: inline-block;
                          color: #000;
                          font-weight: bold;
                          background-color: #add8e6;
                      }
                      .mess-1-1{
                          padding: 8px;
                          border-radius: 8px
                      }
                      .mess-2-2{
                          padding: 8px;
                          border-radius: 8px
                      }
                     .mess-2{
                         display: inline-block;
                         word-wrap:break-word;
                         word-break:break-all;
                         color: #696969;
                         background-color:#fff;
                         padding: 8px;
                         border-radius: 8px
                     }
                     .tot{
                         display: inline-block;
                          40%;
                         word-wrap:break-word;
                         word-break:break-all;
                         color: #fff;
                         float: right;
                         margin-top: 3px;
                     }
                     .bottom-box{
                         position: fixed;
                         left: 0px;
                         bottom: 0px;
                         100%;
                         background-color: #191970;
                         padding-top: 10px
                      }
                  }
            </style>
            
        </head>
        <body>
            <div class="container">
                <span id="is-open">服务器正在连接......</span>
                <span class="tot">当前共有<span id="total">0</span>个窗口在连接!</span>
                <p id="result"></p>
                
                <form>
                    <div class = "bottom-box">
                        <p><span style="color: #fff">昵称:</span><input type="text" id="username"  class="form-control msl"/></p>
                        <p>
                            <input id="message" class="form-control ms">
                            <button id="btn" type="button" class="btn btn-primary">发送</button>
                        </p>
                    </div>
                </form>
    
            </div>
            
    <script>
        $(document).ready(function(){
            
            var timeOut;
            var arrResult = [];
            
            // 设置cookie函数
            function setCookie(cname,cvalue,exdays){
                var d = new Date();
                d.setTime(d.getTime()+(exdays*24*60*60*1000));
                var expires = "expires="+d.toGMTString();
                document.cookie = cname + "=" + cvalue + "; " + expires;
            }
    
            // 取出cookie数据函数
            function getCookie(cname){
                var name = cname + "=";
                var ca = document.cookie.split(';');
                for(var i=0; i<ca.length; i++) {
                    var c = ca[i].trim();
                    if (c.indexOf(name)==0) return c.substring(name.length,c.length);
                }
                return "";
            }
        
    /* 刷新页面时从取出数据初始化页面 */
        
            // 初始化插入昵称
            var usrName = (getCookie("userName") != null)?getCookie("userName"):"";
            $("#username").val(usrName);
            
            setTimeout(function(){
                // 初始化滚动消息到最新
                $("#result").scrollTop(result.scrollHeight);
            },500);
        
            
            // 刷新页面时从redis数据库取出数据初始化页面
            $.post("./ajax.php",{},function(ajaxData){
                var m = JSON.parse(ajaxData);
                for(key in m){
                    arrResult.push(m[key]);
                }
                $("#result").html(arrResult.join(''));
            });
            
    /* 初始化数据结束 */
        
    /* websocket通信 */
            var ws = new WebSocket("ws://47.94.224.241:9503");
        
            ws.onopen=function(){
                $("#is-open").html('服务器连接成功......');
                clearInterval(timeOut);
            }
        
            ws.onmessage=function(res){
                var data=JSON.parse(res.data);
                if(data.userId){
                    window.userId = data.userId;
                }
    
                if(data.total){
                    $("#total").html(data.total);
                    return false;
                }
            
                if( data.cookieUsrName == getCookie("userName") ) {
                    arrResult.push('<p class="mess"><span class="mess-1">' + data.message + '</span><span class="mess-1-1">我</span></p>');
                }else{
                    arrResult.push('<p><span class="mess-2-2">' + data.username + '</span><span class="mess-2">' + data.message + '</span></p>');
                }
    
                // while()里的49要与ajax.php里的lpush方法里的参数49要统一
                while ( arrResult.length > 49) {
                    arrResult.shift();
                }
                
                // 显示在界面上
                var val = arrResult.join("");
                $("#result").html(val);
    
                $("#result").scrollTop(result.scrollHeight);
            }
    
            ws.onclose=function(){
                $("#is-open").html('');
                $("#is-open").html('服务器已断开......');
                
                // 断开连接刷新页面
                timeOut = setInterval(function(){
                    location.replace(location.href);
                }, 1000);
            }
    
            btn.onclick=function(){
                if($("#username").val() == '' || $("#message").val() == '') {
                   
                    // 打开模态框
                    $('#myModal').modal('show');
                }else{
                    
                   /*
                     * 组装数据,数据是在js里组装的,swoole服务器只是转发了一下数据并存入redis数据库
                     *
                     * 判断“我”的方法:
                     * 1. 一种是判断fromuserid,可以判断到具体窗口,一个浏览器打开3个窗口就是3个不同的“我”;
                     * 2. 另一种是判断cookie或session里存储的用户名,即cookieUsrName键,一个浏览器认
                     *     为是一个用户,这里是用昵称代替了。
                     */
                    var data={ fromuserid: window.userId, username: username.value, message: message.value, cookieUsrName: getCookie("userName") } ;
                   
                    //对象转JSON字符串发送到服务器
                    ws.send( JSON.stringify(data) );
                    message.value='';
               }
            }
        
            username.onkeyup = function() {
                   //昵称存入cookie
                   setCookie("userName", $("#username").val(), 7);
            }
        });
    </script>
    
    <!-- 模态框 -->
    <div class="modal fade" id="myModal">
      <div class="modal-dialog">
        <div class="modal-content">
     
          <!-- 模态框头部 -->
          <div class="modal-header">
            <h4 class="modal-title">
                <i class="fa fa-exclamation-circle fa-lg" style="color: red"></i>
                错误提示:
            </h4>
            <button type="button" class="close" data-dismiss="modal">&times;</button>
          </div>
     
          <!-- 模态框主体 -->
          <div class="modal-body">
            “昵称”和“消息”内容都不允许为空,请重新输入!
          </div>
     
          <!-- 模态框底部 -->
          <div class="modal-footer">
            <button type="button" class="btn btn-secondary" data-dismiss="modal">关闭</button>
          </div>
          
          </div>
      </div>
    </div>
    
    </body>
    </html>

    swooleServer.php

    <?php
    $ws = new swoole_websocket_server("0.0.0.0", 9503, SWOOLE_PROCESS);
    
    $ws->set(array(
        'reactor_num' => 2, //reactor thread num
        'worker_num' => 4,    //worker process num
        'backlog' => 128,   //listen backlog
        'max_conn' => 10000, 
        'max_request' => 50,
        'dispatch_mode' => 1,
        'daemonize' => 1
    ));
    
    $ws->on('open', function ($ws, $request) {
        
        $tot = count($ws->connections);
        $ws->push($request->fd, json_encode(['userId' => $request->fd, 'total' => $tot]));
        
    });
    
    $ws->on('message', function ($ws, $frame) {
        // 每个用户发送的消息向所有用户转发
        foreach($ws->connections as $value) {
            $ws->push($value, $frame->data);
        }

    // 向redis数据库写入数据,数据类型“列表”
    $redis = new Redis(); $redis->connect('127.0.0.1', 6379); $redis->lpush("messages", $frame->data); // 超过100条数据开始删除旧数据 while($redis->llen("messages") > 100) { $redis->rpop("messages"); } }); $ws->on('close', function ($ws, $fd) { $i = 0; foreach($ws->connections as $v) { if($v == $fd) { unset($ws->connections[$i]); } $i++; } }); $ws->start(); ?>

    ajax.php

    <?php
        $redis = new Redis();
        $redis->connect('127.0.0.1', 6379);
        $arrList = $redis->lrange("messages", 0, 20);
        $arrValue = [];
        while(count($arrList) > 0){
            $v = array_pop($arrList);
            $arrVal = json_decode($v, true);
            if($arrVal['cookieUsrName'] == $_COOKIE['userName']) {
                array_push($arrValue, '<p class="mess"><span class="mess-1">' . $arrVal['message'] . '</span><span class="mess-1-1">我</span></p>');
            }else{
                array_push($arrValue, '<p><span class="mess-2-2">' . $arrVal['username'] . '</span><span class="mess-2">' . $arrVal['message'] . '</span></p>');
            }
        }
        
        echo json_encode($arrValue);
    ?>

    可以通过下面的页面查看redis数据库里的内容,不用去服务器端查看效果。

    showRedis.php

    <?php
        //连接本地的 Redis 服务
       $redis = new Redis();
       $redis->connect('127.0.0.1', 6379);
       
       // 获取存储的数据并输出
       $arList = $redis->lrange("messages", 0 ,100);
       
       echo '当前显示内容->' . json_decode($arList[0], true)["username"] . ":“" . json_decode($arList[0], true)["message"] . "”";
    echo "<pre>"; print_r($arList); echo "</pre>";?>
  • 相关阅读:
    面向对象三大特征之多态——Java笔记(七)
    面向对象三大特征之继承(extends)——Java笔记(六)
    this、访问修饰符——Java笔记(五)
    面向对象三大特征之封装与static——(Java学习笔记四)
    初识Java——(Java学习笔记一)
    HTTP/3 简介
    iis 500.19错误解决过程记录
    排序陷阱 List.Sort Linq.OrderBy
    锁的封装 读写锁、lock
    时间“Thu Aug 14 2014 14:28:06 GMT+0800”的转换
  • 原文地址:https://www.cnblogs.com/qingsong/p/11442219.html
Copyright © 2020-2023  润新知