首先,先打开官网手册 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