首先,先打開官網手冊 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
