workerman php的使用,进行定时任务、websocket、tcp等协议开发

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调试结果发现成功了。

不成功排查:

  1. 服务端没有启动

  2. 服务器端口没有开放或防火墙没有设置开放

  3. 客户端和服务端用的协议不一致

  4. 服务端代码出错


注意事项:

  1. 每次修改逻辑代码后都需要重新执行启动(重启)服务端才有效,因为这个常驻内存的高效应用(用SVN开发的话可以在提交SVN后回调加入重启命令比较方便)。

  2. 长链接一定要设置心跳模式,否则容易被系统终止进程


常用命令:

php server.php connections
php server.php stop
php server.php restart
php server.php reload 


其他参考:https://github.com/walkor/workerman


评论/留言