zoukankan      html  css  js  c++  java
  • workerman搭建聊天室

    首先,先打开官网手册   http://doc.workerman.net/

    根据手册里安装里的提示,完成环境检测,和安装对应的扩展,并把对应的WorkerMan代码包下载解压至根目录

    在根目录下创建一个index.php

    index.php代码如下:

    <?php
    use WorkermanWorker;
    require_once __DIR__ . '/Workerman/Autoloader.php';
    use WorkermanLibTimer;
    
    
    Worker::$daemonize = true;
    // 所有的打印输出全部保存在/stdout.log文件中
    Worker::$stdoutFile = '/stdout.log';
    
    // 注意:这里与上个例子不同,使用的是websocket协议
    $ws_worker = new Worker("websocket://0.0.0.0:2999");
    
    // 启动1个进程对外提供服务
    $ws_worker->count = 1;
    
    // 设置实例的名称
    $ws_worker->name = 'Worker1';
    
    //定义全局变量
    $user_ip = [];
    
    // 心跳间隔120秒
    define('HEARTBEAT_TIME', 120);
    
    // 当收到客户端发来的数据后返回hello $data给客户端
    //闭包使用use传递参数进行使用
    $ws_worker->onMessage = function($connection, $data)use($ws_worker)
    {    
        // 给connection临时设置一个lastMessageTime属性,用来记录上次收到消息的时间
        $connection->lastMessageTime = time();
        
        global $user_ip;
        file_put_contents('666.txt',$data, FILE_APPEND | LOCK_EX);
        
        //用户发送的信息内容
        $content = substr($data,mb_strpos($data,':') + 1,mb_strlen($data));
        //用户发送信息的状态请求,比如,登录,发送消息等等
        $sort = strstr($data,':',true);
        //获取用户的ip
        $ip = $connection->getRemoteIp();
        if($sort == 'login'){
            //判断用户昵称是否重复
            $array_search = array_search($content,$user_ip, false);
            if( $array_search != $ip && !empty($array_search)){
                //触发回调,关闭服务器和客户端链接
                $connection->close('sort:'.'401');
            }
            if(!array_key_exists($ip,$user_ip)){
                //记录登录时间
                echo '登录ip:'.$ip.'    登录时间:'.date('Y-m-d H:i:s', time()).'
    ';
            }
            // 录入ip和昵称
            $user_ip[$ip] = $content;
            //登录成功,返回200
            $connection->send('sort:'.'200');
            
        }else if($sort == 'text'){
            //获取用户发送的消息,并返回
            // $connection->send('text:'.$user_ip[$ip].':'.$content);
            
            //广播,通过$ws_worker->connections获取所有连接服务端的对象,循环给所有在线用户推送信息
            foreach($ws_worker->connections as $connection)
            {
                $connection->send('text:'.$user_ip[$ip].'发送消息:'.$content);
            }
        }else{
            //未知错误,返回500
            $connection->send('sort:'.'500');
        }
        
    };
    
    // 进程启动后设置一个每秒运行一次的定时器
    $ws_worker->onWorkerStart = function($ws_worker) {
        Timer::add(1, function()use($ws_worker){
            $time_now = time();
            foreach($ws_worker->connections as $connection) {
                // 有可能该connection还没收到过消息,则lastMessageTime设置为当前时间
                if (empty($connection->lastMessageTime)) {
                    $connection->lastMessageTime = $time_now;
                    continue;
                }
                // 上次通讯时间间隔大于心跳间隔,则认为客户端已经下线,关闭连接,返回402
                if ($time_now - $connection->lastMessageTime > HEARTBEAT_TIME) {
                    $connection->close('sort:'.'402');
                }
            }
        });
    };
    
    //用户断开连接时触发函数
    $ws_worker->onClose = function($connection)
    {
        global $user_ip;
        //清除用户的ip和用户名
        $ip = $connection->getRemoteIp();
        unset($user_ip[$ip]);
        echo 'ip:'. $ip . '      下线时间:'.date('Y-m-d H:i:s', time()).'
    ';
    };
    
    // 运行worker
    Worker::runAll();

    然后在根目录中的index.html写入以下代码

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="https://libs.baidu.com/jquery/1.8.3/jquery.min.js"></script>
    </head>
    <body>
        <div>你的昵称:<input type="text" id="username" value=""/></div>
        <div>
            回复内容:
            <textarea style=" 500px;height: 100px" id="content" value=''></textarea>
        </div>
        <div>
            <input type="button" onclick="login()" value="连接服务器">
            <input type="button" onclick="send()" value="发送消息">
            <input type="button" onclick="quit()" value="退出">
        </div>
     
        <script>
    
            var socket = null;  //将socket实例保存到变量中
            var isLogin = false;    //登录标识符
            
            var ws;
    
            function login(){
                var name = document.getElementById('username').value;
                if(name.length == 0 || name == ''){
                    alert('请输入昵称');
                    return false;
                }
                ws = new WebSocket("ws://www.xxx.com:2999");
                
                ws.onopen = function() {
                    ws.send('login:'+name);
                    ws.onmessage = function(e) {
                        console.log(e);
                        callback(e);
                    }
                }
            }
    
            function send(){
                if(!isLogin){
                    alert('请先连接服务器');
                    return false;
                }
                
                var content =document.getElementById('content').value;
                
                ws.send('text:' + content);
                ws.onmessage = function(e) {
                    callback(e);
                }
            }
            
            function quit(){
                if(!isLogin){
                    alert('请先连接服务器');
                }
                ws.send('quit');
                ws.onmessage = function(e){
                    callback(e);
                }
            }
            
            //返回值处理
            function callback(e){
                //返回的状态
                var sort = e.data.substring(0,e.data.indexOf(':'));
                //返回的内容
                var content = e.data.substring(e.data.indexOf(':')+1);
                
                if(sort == 'text'){
                    alert(content);
                }else if(sort == 'sort'){
                    
                    if(content == 401){
                        alert('用户名重复,连接失败');
                    }else if(content == 200){
                        isLogin = true;
                        alert('连接成功');
                    }else if(content == 402){
                        isLogin = false;
                        alert('长时间未发消息,已断开连接,请重新连接服务器');
                    }else if(content == 202){
                        isLogin = false;
                        alert('成功断开连接');
                    }else if(content == 500){
                        alert('未知错误');
                    }else{
                        alert('未知错误');
                    }
                    
                }else{
                    alert('连接失败');
                }
            }
        </script>
    </body>
    </html>

    弄好了之后,打开终端,cd 至网站根目录,执行index.php脚本,监听端口,并加入守护进程

    php index.php start -d

    执行成功,那么你的一个简单的即时通讯功能就完成了

    测试:两个不同的用户登录网页,输入昵称,连接服务器,其中一个发送消息,另一个在页面中有收到

    那么恭喜你,一个简单的即时通讯功能就这样做出来了

    参考文章:https://blog.csdn.net/qq_33862644/article/details/79554321

  • 相关阅读:
    3年度研发项目情况项目目标文档
    2系统利益相关者描述案例
    讨论结果
    本学期《软件需求分析》需要掌握的内容(个人总结)
    第二周进度条
    四则运算
    第一周进度记录
    java web
    ke tang zuo ye
    2015-05-26 随笔
  • 原文地址:https://www.cnblogs.com/junyi-bk/p/12485506.html
Copyright © 2011-2022 走看看