workerman是一个高性能的PHP socket 服务器框架,workerman基于PHP多进程以及libevent事件轮询库,PHP开发者只要实现一两个接口,便可以开发出自己的网络应用,例如Rpc服务、聊天室服务器、手机游戏服务器等。
workerman的目标是让PHP开发者更容易的开发出基于socket的高性能的应用服务,而不用去了解PHP socket以及PHP多进程细节。 workerman本身是一个PHP多进程服务器框架,具有PHP进程管理以及socket通信的模块,所以不依赖php-fpm、nginx或者apache等这些容器便可以独立运行。
<?php #服务端(server.php) require_once __DIR__ . '/../../vendor/autoload.php'; require __DIR__.'/base.php';//自己的业务逻辑 use Workerman\Worker; use Workerman\Lib\Timer; use wegame\test; // 心跳间隔30秒 define('HEARTBEAT_TIME', 30); $worker = new Worker('websocket://0.0.0.0:1234');//监听地址和端口,支持http、tcp、text、ws和自定义协议 $worker->onMessage = function($connection, $data) { // 给connection临时设置一个lastMessageTime属性,用来记录上次收到消息的时间 $connection->lastMessageTime = time(); // 其它业务逻辑... $connection->send('hello your params:'.$data);//返回内容 // $connection->send((new test())->run($data));//自己的业务逻辑 }; // 4 processes $worker->count = 1; // Emitted when new connection come $worker->onConnect = function ($connection) { echo "New connection\n"; }; // Emitted when connection closed $worker->onClose = function ($connection) { //DebugServer::debug_log('test','close'); echo "Connection closed\n"; }; // 进程启动后设置一个每10秒运行一次的定时器 $worker->onWorkerStart = function($worker) { Timer::add(10, function()use($worker){ $time_now = time(); foreach($worker->connections as $connection) { // 有可能该connection还没收到过消息,则lastMessageTime设置为当前时间 if (empty($connection->lastMessageTime)) { $connection->lastMessageTime = $time_now; continue; } // 上次通讯时间间隔大于心跳间隔,则认为客户端已经下线,关闭连接 if ($time_now - $connection->lastMessageTime > HEARTBEAT_TIME) { $connection->close(); } } }); }; Worker::runAll(); #在命令行执行启动 php server.php start -d
启动后在客户端进行测试(html即可):
<!DOCTYPE HTML> <html lang="zh"> <head> <meta charset="utf-8"> <title>test</title> <script type="text/javascript"> function WebSocketTest() { if ("WebSocket" in window) { alert("您的浏览器支持 WebSocket!"); // 打开一个 web socket var ws = new WebSocket("ws://服务器IP:端口"); ws.onopen = function () { // Web Socket 已连接上,使用 send() 方法发送数据 ws.send("发送的数据"); alert("数据发送中..."); }; ws.onmessage = function (evt) { var received_msg = evt.data; alert("数据已接收..."); }; ws.onclose = function () { // 关闭 websocket alert("连接已关闭..."); }; } else { // 浏览器不支持 WebSocket alert("您的浏览器不支持 WebSocket!"); } } </script> </head> <body> <div id="sse"> <a href="javascript:WebSocketTest()">运行 WebSocket</a> </div> </body> </html>
查看上面的html调试结果发现成功了。
不成功排查:
服务端没有启动
服务器端口没有开放或防火墙没有设置开放
客户端和服务端用的协议不一致
服务端代码出错
注意事项:
每次修改逻辑代码后都需要重新执行启动(重启)服务端才有效,因为这个常驻内存的高效应用(用SVN开发的话可以在提交SVN后回调加入重启命令比较方便)。
长链接一定要设置心跳模式,否则容易被系统终止进程
常用命令:
php server.php connections
php server.php stop
php server.php restart
php server.php reload
其他参考:https://github.com/walkor/workerman