workerman搭建聊天室


首先,先打開官網手冊   http://doc.workerman.net/

根據手冊里安裝里的提示,完成環境檢測,和安裝對應的擴展,並把對應的WorkerMan代碼包下載解壓至根目錄

在根目錄下創建一個index.php

index.php代碼如下:

<?php
use Workerman\Worker;
require_once __DIR__ . '/Workerman/Autoloader.php';
use Workerman\Lib\Timer;


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()).'\n';
        }
        // 錄入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()).'\n';
};

// 運行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="width: 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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM