Giter Site home page Giter Site logo

walkor / workerman Goto Github PK

View Code? Open in Web Editor NEW
10.9K 467.0 2.3K 3.51 MB

An asynchronous event driven PHP socket framework. Supports HTTP, Websocket, SSL and other custom protocols.

Home Page: http://www.workerman.net

License: MIT License

PHP 100.00%
websocket timer socket event-driven asynchronous ws wss high-performance socket-server tcp

workerman's People

Contributors

2276225819 avatar akotulu avatar ares333 avatar blogdaren avatar chance-fyi avatar codekissyoung avatar forkeer avatar her-cat avatar hkui avatar ishland avatar jfcherng avatar jhdxr avatar joanhey avatar joelhy avatar linkec avatar luckycyborg avatar luzrain avatar malacca avatar mouyong avatar mowangjuanzi avatar sm2017 avatar sukui avatar tianhe1986 avatar twomiao avatar victorruan avatar vponomarev avatar walkor avatar xheaven avatar xuanyanwow avatar yurunsoft avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

workerman's Issues

workerman 进程存在,但是status失败,是什么情况?

1:
php /data/program/Crontab/workerman/start.php status
Workerman[/data/program/Crontab/workerman/start.php] not run
用户定义信号 2

2:
ps -aux | grep WorkerMan
Warning: bad syntax, perhaps a bogus '-'? See /usr/share/doc/procps-3.2.7/FAQ
appweb 23675 0.0 0.0 193940 2184 ? S Sep21 0:00 WorkerMan: master process start_file=/data/program/Crontab/workerman/start.php
appweb 23676 0.0 0.0 193940 1760 ? S Sep21 0:00 WorkerMan: worker process crontab none
appweb 23696 0.0 0.0 61192 776 pts/2 S+ 09:58 0:00 grep WorkerMan

这个是不是有问题?  进程存在,但status有问题。

如何扩展Connection类?

websocket类的Connection是TcpConnection,我想给TcpConnection扩展一些方法,或者封装send方法。如何做才优雅?
注:并不想写成自定义Connection然后继承TcpConnection,因为只是更改encode、decode的话,还是很多功能无法实现。

Child Process' STDOUT

I am trying to debug an issue, but this issue occurs in a child process of Workerman. How can I get it's STDOUT to be shared with the parent in order to see it in the process, or directed into a file?

如何安装redis扩展

已经安装程序,并且能够正常运行。
使用redis扩展,使用 pecl上,phpredis 2.2.5
下面是关于redis存储数据,扩展编写

function set($key,$value,$ttl = 0)
{
$value = is_array($value) ? json_encode($value) : $value;
$this->handle->set($key,$value);
return $value;
}

function get($key,$use_cache = true)
{
    $value = $this->handle->get($key);

    $json = json_decode($value,true);

    return ($json == null) ? $value : $json;
}

启动程序是,一直报错
Invalid argument supplied for foreach() in /home/wwwroot/default/websocket/GatewayWorker/BusinessWorker.php on line 108

求解释,谢谢

单机连接数超过6000的时候断开socket链接client_id依然存在

soory,又来麻烦你了,已经升级到2.0
单机连接数超过6000的时断开socket链接,有一定几率client_id依然存在
一个终端对应两个或多个client_id,向这两个client_id发广播,该终端都能收到

实际应用中的表象
我从一个房间A进入另一个房间B,在房间B还能收到A房间的信息

workerman是否可以做客户端

看了一遍文档,workerman貌似只能用作服务器端。是否支持workerman作为客户端连接socket(长连接),接收数据之后,触发处理数据逻辑?

onWorkerStop的疑问

我在定时器指定的方法里面设置了运行次数的检查,达到次数的时候,执行Worker::stopAll()。但是发现这样使用,无法启用新的进程来处理。

我主要用来在服务器跑后台数据。(下面我写的大概结构)

$worker->count = n;
$worker->onWorkerStart() = function ($worker) {
Timer::add(0.5, 'taskGenerator', array());
}

taskGenerator(){
static $runtimes = 0;
$runtims++;

//do some logic

if ($runtimes > MAX_RUNTIMES) {
    Worker:stopAll();
}

}

运行抛错

执行./ workerman start
出现下面的错误:

PHP Fatal error:  Call to undefined function posix_getpwuid() in /var/www/html/workerman-master/workerman/bin/workermand on line 92

Fatal error: Call to undefined function posix_getpwuid() in /var/www/html/workerman-master/workerman/bin/workermand on line 92

gateway模型下,如果服务器一直主动push消息给客户端,客户端直接拔掉网线,心跳机制失效

我们采用的是gateway/worker模型,在我们的工作场景中,客户端会每隔4S,发送心跳给服务器,服务器不会主动发送心跳消息。
使用的心跳机制同下:
$gateway = new Gateway("Websocket://0.0.0.0:8585");
$gateway->pingInterval = 4;
$gateway->pingNotResponseLimit = 2;
$gateway->pingData = '';
虽然服务器不会发送心跳消息给客户端,但是,服务器是需要不断的PUSH正常的消息给服务器。
假如在服务器不断PUSH的过程中,客户端直接拔掉网线,我们发现,服务器不能识别出客户端已经断网,心跳机制失效。
但是,如果我们不让服务器PUSH正常消息的话,只要客户端拔掉网线,8s过后,服务器能够识别到客户端断网。
请问这是什么原因造成的呢?谢谢!

worker和connection中都维护了一个onmessage?

能不能举个具体的例子说明一下为何要这样?在两个回调中都可以做信息发送,有什么区别的地方?
(区别是只针对当前连接有效,是不是假设在 worker中的onmessage的参数 connection中读取
$connection->worker->connections 然后遍历 绑定onmessage 是无效的。但还是想不出具体的应用场景。动态改变?

Workerman的session问题

  • 1.没有启用session的时候,调用了 sessionWriteClose,想开启的时候无法开启
  • 2.无法识别session_save_path的redis,memcache类型

我的workerman服务在运行时(start), 然后reload或restart都会出现异常情况,无法正常启动

我的环境是MacOS系统,PHP是5.5.37
我启动方法是: php app/workers/dssproxy.php start
显示结果如下:
Workerman[app/workers/dssproxy.php] start in DEBUG mode
----------------------- WORKERMAN -----------------------------
Workerman version:3.3.4 PHP version:5.5.37
------------------------ WORKERS -------------------------------
user worker listen processes status

chenbin none websocket://0.0.0.0:2347 4 [OK]

Press Ctrl-C to quit. Start success

现在通过ps -ef | grep "dssproxy.php" | grep -v "grep", 结果如下:
501 14662 4058 0 10:17上午 ttys002 0:00.05 php app/workers/dssproxy.php start
501 14663 14662 0 10:17上午 ttys002 0:00.16 php app/workers/dssproxy.php start
501 14664 14662 0 10:17上午 ttys002 0:00.16 php app/workers/dssproxy.php start
501 14665 14662 0 10:17上午 ttys002 0:00.16 php app/workers/dssproxy.php start
501 14666 14662 0 10:17上午 ttys002 0:00.16 php app/workers/dssproxy.php start

现在我使用: php app/workers/dssproxy.php reload(在另一终端), 结果如下:
Workerman[app/workers/dssproxy.php] reload
Workerman[app/workers/dssproxy.php] reload

现查看另一终端,结果如下:(start时的终端)
Workerman[app/workers/dssproxy.php] start in DEBUG mode
----------------------- WORKERMAN -----------------------------
Workerman version:3.3.4 PHP version:5.5.37
------------------------ WORKERS -------------------------------
user worker listen processes status

chenbin none websocket://0.0.0.0:2347 4 [OK]

Press Ctrl-C to quit. Start success.
Segmentation fault: 11

这个时候出现11的错误,并且回到命令行状态
现在再通过ps -ef | grep "dssproxy.php" | grep -v "grep", 结果如下:
501 14663 1 0 10:17上午 ttys002 0:00.24 php app/workers/dssproxy.php start
501 14664 1 0 10:17上午 ttys002 0:00.24 php app/workers/dssproxy.php start
501 14665 1 0 10:17上午 ttys002 0:00.24 php app/workers/dssproxy.php start
501 14666 1 0 10:17上午 ttys002 0:00.24 php app/workers/dssproxy.php start
从上看应该是master部分被kill掉了,而且现在无法start或restart, 因为port仍占用着,用下列命令:
php app/workers/dssproxy.php restart
报错: stream_socket_server(): unable to connect to tcp://0.0.0.0:2347 (Address already in use)

请问这是什么原因?reload要怎么操作?应该注意些什么?

关于TcpConnection.php里的四个闭包函数的疑问

我在看项目源码时,发现在 TcpConnection.php第502行的pipe函数中有四个闭包函数,PHPStrom提示这些函数的参数并没有被用到。我看了一下,确实是这样。这样写有什么特别的含义吗?

代码如下

public function pipe($dest)
    {
        $source              = $this;
        $this->onMessage     = function ($source, $data) use ($dest) {
            /* $source,$data没有使用 */
            $dest->send($data);
        };
        $this->onClose       = function ($source) use ($dest) {
            /* $source没有使用 */
            $dest->destroy();
        };
        $dest->onBufferFull  = function ($dest) use ($source) {
            /* $dest没有使用 */
            $source->pauseRecv();
        };
        $dest->onBufferDrain = function ($dest) use ($source) {
            /* $dest没有使用 */
            $source->resumeRecv();
        };
    }

English docs

I really, really like workerman. After a few tests I did with it, I want to put it into my project under production. In order to really do so, I need to know more of the API. Like how to associate worker names, which on{...} methods exist and which variables can be set.

Further, I would like to be able to give my server some arguments of its own. It will be started by a parent process and receive its arguments via command line. Can I still get the arguments for my script even after workerman took them?

Kind regards, Ingwie.

Restart on file change

I'm currently restarting workerman over and over and over each time a file changes.

It'd be handy to have a way to restart it faster. Any idea?

My idea with watching files comes from the things the JavaScript community does; where they watch files for their last modified date, and if it was modified, the entire service is restarted. Usually used for development and disabled in production, of course.

路由规则问题

在我们的项目里面,存在这样一种情况,gateway/business模型中,business收到客户端的某一种命令,其实应该所有的business都执行某种操作。所以,我想在gateway解析出我们自定义的协议之后,根据协议的命令字来决定是随机路由还是全部路由。
目前自定义的路由也只能路由给一个business。
$gateway->router = function($worker_connections, $client_connection, $cmd, $buffer)
{
//这里根据$buffer中我们自定义的命令来决定是随机转发还是全部转发
if(特殊命令需要全部转发)
{
return $worker_connections;
}
return $worker_connections[array_rand($worker_connections)];
};

sendToWorker里面就需要做如下改动:
// 调用路由函数,选择一个worker把请求转发给它
$worker_connections = call_user_func($this->router, $this->_workerConnections, $connection, $cmd, $body);
foreach ($worker_connections as $worker_connection)
{
if(false === $worker_connection->send($gateway_data))
{
$msg = "SendBufferToWorker fail. May be the send buffer are overflow";
$this->log($msg);
return false;
}
}

这样可行不?谢谢。

WS协议onMessage回调函数问题?

为什么WebSocket Client(WS协议)连接后,针对onMessage回调,必须事前在onConnect里先呼叫:
$connection->send('message'), 否则onMessage不回有任何消息回应。以下是我的代码。

$ws_worker = new Worker("websocket://0.0.0.0:2347");
// 启动4个进程对外提供服务
$ws_worker->count = 4;

$ws_worker->uidConnections = array();

// 当收到客户端发来的数据后返回hello $data给客户端
$ws_worker->onConnect = function($connection)
{
process($connection);
};

function process($connection)
{
$wsConnection = new AsyncTcpConnection('ws://127.0.0.1:2346');

$wsConnection->onConnect = function($conn){
     $conn->send('hello'); //如果没有这一句,下面的onMessage不回收到任何回复。
};
$wsConnection->onMessage = function($conn, $data) {
     echo 'receive:'.$data;
};
// 连接上发生错误时,一般是连接远程websocket服务器失败错误
$wsConnection->onError = function($conn, $code, $msg){
    echo "error: $msg\n";
};
// 当连接远程websocket服务器的连接断开时
$wsConnection->onClose = function($conn){
    echo "connection closed\n";
};
// 设置好以上各种回调后,执行连接操作
$wsConnection->connect();

}
// 运行worker
Worker::runAll();

以下是另外一个websocket代码:

// 创建一个Worker监听2346端口,使用websocket协议通讯
$ws_worker = new Worker("websocket://0.0.0.0:2346");

// 启动4个进程对外提供服务
$ws_worker->count = 3;

// 当收到客户端发来的数据后返回hello $data给客户端
$ws_worker->onConnect = function ($connection) {
echo "connection successful\n";
process($connection);
};

function process($connection)
{
$time_interval = 3;
Timer::add($time_interval, function () use ($connection) {
static $i = 1;
$connection->send('dds-'. $i . "\n");
$i++;
});
}

// 运行worker
Worker::runAll();

Get IP from TCP connection

Is it possible like title said ? (maybe via socket_getpeername) ??

i use:


require_once './Autoloader.php';
use Workerman\Worker;

// #### create socket and listen 1234 port ####
$tcp_worker = new Worker("tcp://0.0.0.0:1234");

....

Add a pipe server

Really cool functionality would be the ability to have a server that can react to BASH stdin, so onMessage gets called every time a process writes to the pipe. I've tried to implement this myself but i'm really stuck!

能收到心跳,但是Gateway::isOnline却返回false

workerman 3.2.1:

心跳是这么配置的。
$gateway->pingInterval = 4;
$gateway->pingNotResponseLimit = 2;
$gateway->pingData = '';
然后客户端每4s发送心跳数据给服务器。我们的服务器收到之后,会根据
$key = $_SERVER['GATEWAY_CLIENT_ID'];来存储到memcache里面。而且是8s的过期时间。
此服务运行了2天左右(客户端保持连接2天不断线),出现了异常情况。
我们有两个客户端工控设备。这两个设备一直可以往服务器传输数据,服务器也可以往设备发送数据。
但是,Gateway::isOnline里面却返回false,也就是memcache里面没有gateway-clientid这个客户端。但是
数据却是正常传输的。而我们自己也保存了clientid这个key到memcache,因为我们是定时刷新的。只要客户端有心跳数据来就会刷新,所以,我们里面能看到这个连接,wireshark抓包显示服务器和客户端的连接确实存在。所以应该是gateway进程空间里面保持了这个连接。但是memcache里面却没有,所以business里面看不到这个连接。

invliad _statisticsFile path

PHP Warning: readfile(/var/folders/gp/gfm74_6x0pn2lc0xm6xzsj140000gn/T/workerman.status): failed to ope
n stream: No such file or directory in /Users/vb2005xu/workspace/workman-console/vendor/workerman/workerrman/Worker.php on line 563

case 'status':
                // 尝试删除统计文件,避免脏数据
                if(is_file(self::$_statisticsFile))
                {
                    @unlink(self::$_statisticsFile);
                }
                // 向主进程发送 SIGUSR2 信号 ,然后主进程会向所有子进程发送 SIGUSR2 信号
                // 所有进程收到 SIGUSR2 信号后会向 $_statisticsFile 写入自己的状态
                posix_kill($master_pid, SIGUSR2);
                // 睡眠100毫秒,等待子进程将自己的状态写入$_statisticsFile指定的文件
                usleep(100000);
                // 展示状态
                readfile(self::$_statisticsFile);
                exit(0);

文件都不存在,直接读取合适吗?

主进程如何同子进程共享数据

使用过程中,发现onWorkerStart里面无法使用主进程中定义的常量。也无法直接在onWorkerStart里面引入文件定义的变量。有什么特定的引入方法吗?

[PATCH] fix workman some bug

diff --git a/Core/Lib/Checker.php b/Core/Lib/Checker.php
index 0018413..7489b6f 100755
--- a/Core/Lib/Checker.php
+++ b/Core/Lib/Checker.php
@@ -272,7 +272,7 @@ class Checker
     public static function checkPidFile()
     {
         // 已经有进程pid可能server已经启动
-        if(@file_get_contents(WORKERMAN_PID_FILE))
+        if(is_file(WORKERMAN_PID_FILE) && file_get_contents(WORKERMAN_PID_FILE))
         {
             \Man\Core\Master::notice("\033[33;40mWorkerman already started\033[0m", true);
             exit;
diff --git a/Core/Master.php b/Core/Master.php
index da0e084..e4c4423 100755
--- a/Core/Master.php
+++ b/Core/Master.php
@@ -344,6 +344,7 @@ class Master
                 if(self::createOneWorker($worker_name) == 0)
                 {
                     self::notice("Worker exit unexpected");
+                    sleep(5);
                     exit(500);
                 }
             }
diff --git a/Core/SocketWorker.php b/Core/SocketWorker.php
index d469096..51d3691 100755
--- a/Core/SocketWorker.php
+++ b/Core/SocketWorker.php
@@ -201,7 +201,7 @@ abstract class SocketWorker extends AbstractWorker
         $this->installSignal();

         // 触发该worker进程onStart事件,该进程整个生命周期只触发一次
-        if($this->onStart())
+        if(!$this->onStart())
         {
             return;
         }
@@ -230,7 +230,7 @@ abstract class SocketWorker extends AbstractWorker
     public function stop()
     {
         // 触发该worker进程onStop事件
-        if($this->onStop())
+        if(!$this->onStop())
         {
             return;
         }
diff --git a/bin/workermand b/bin/workermand
index 9a687f5..43fa9a5 100755
--- a/bin/workermand
+++ b/bin/workermand
@@ -172,7 +172,8 @@ function force_kill()

 function stop_and_wait($wait_time = 6)
 {
-    $pid = @file_get_contents(WORKERMAN_PID_FILE);
+    $pid = "";
+    if(is_file(WORKERMAN_PID_FILE)) $pid = file_get_contents(WORKERMAN_PID_FILE);
     if(empty($pid))
     {
         //exit("server not running?\n");

如何优雅的实现应用层路由

例如我的上行包和下行包都有“route”字段,常见值:“push.error.auth.not_login”、“post.auth.login”
如何优雅的进行路由,workerman中是否已有接口?如果没有,应该如何实现才优雅?是否可以使用某个现有的composer route package来实现?

workerman run in hhvm file not found

debian 7 安装了hhvm 运行 workerman 的时候,报出大量的文件找不到。如下:

Fatal error: Class undefined: Lib\StoreDriver\File in /mnt/hgfs/d/php/workerman/applications/Demo/Lib/Store.php on line 60
Worker[BusinessWorker:57934]:WORKER EXIT UNEXPECTED File not found: /mnt/hgfs/d/php/workerman/applications/Demo/Config/Store.php in on line -1

Fatal error: Class undefined: Lib\StoreDriver\File in /mnt/hgfs/d/php/workerman/applications/Demo/Lib/Store.php on line 60

Fatal error: Class undefined: Lib\StoreDriver\File in /mnt/hgfs/d/php/workerman/applications/Demo/Lib/Store.php on line 60

Fatal error: Class undefined: Lib\StoreDriver\File in /mnt/hgfs/d/php/workerman/applications/Demo/Lib/Store.php on line 60
Worker[BusinessWorker:57953]:WORKER EXIT UNEXPECTED Class undefined: Lib\StoreDriver\File in on line -1
Worker[BusinessWorker:57938]:WORKER EXIT UNEXPECTED Class undefined: Config\Store in on line -1
Worker[BusinessWorker:57957]:WORKER EXIT UNEXPECTED Class undefined: Config\Store in on line -1
Worker[BusinessWorker:57962]:WORKER EXIT UNEXPECTED Class undefined: Lib\Store in on line -1
Worker[BusinessWorker:57954]:WORKER EXIT UNEXPECTED Class undefined: Config\Store in on line -1
Worker[BusinessWorker:57959]:WORKER EXIT UNEXPECTED Class undefined: Config\Store in on line -1
Worker[BusinessWorker:57966]:WORKER EXIT UNEXPECTED Class undefined: Lib\StoreDriver\File in on line -1
Worker[BusinessWorker:57964]:WORKER EXIT UNEXPECTED Class undefined: Lib\StoreDriver\File in on line -1
Worker[BusinessWorker:57951]:WORKER EXIT UNEXPECTED Class undefined: Config\Store in on line -1
Worker[BusinessWorker:57939]:WORKER EXIT UNEXPECTED Class undefined: Config\Store in on line -1
Worker[BusinessWorker:57971]:WORKER EXIT UNEXPECTED Class undefined: Lib\StoreDriver\File in on line -1
Worker[BusinessWorker:57980]:WORKER EXIT UNEXPECTED Class undefined: Lib\StoreDriver\File in on line -1
^C

Programaticaly obtain stats

Is there a way to obtain the workerman statistics from within the code? Would be very useful for a monitoring component I am working on! :)

求助:storeClientAddress fail

大概500人在线,时间久了就报如下错误,重启后正常
2015-12-11 14:53:42 createGlobalClientId fail GatewayWorker\Lib\StoreDriver\Redis :
2015-12-11 14:53:42 storeClientAddress fail.

redis用的内网地址,cpu占用20%左右,大神帮分析下原因出在哪?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.