windows如何实例两个worker(socket worker 与 websocket worker如何通讯)

windows如何实例两个worker


QQ图片20150706102626.jpg


现在要实例如上图的应用,只是简单DEMO用。workerman一个实例worker2(自定义协议)用来与设备通信,另一个实例worker1(websocker)用来与前端页面通信,通过前端页面给worker2指令,并将worker2收到的数据表现在前端页面。

//ini_set("error_reporting","E_ALL & ~E_NOTICE");
use Workerman\Worker;
require_once __DIR__ . '/../../Workerman/Autoloader.php';

// 创建一个Worker监听2347端口,不使用任何应用层协议
$worker1 = new Worker("Websocket://0.0.0.0:23456");
$worker2 = new Worker("tcp://0.0.0.0:5555");


// 启动1个进程对外提供服务
$worker1->count = 1;
$worker2->count = 1;

// 当客户端发来数据时
$worker1->onMessage = function($connection, $data)
{
// 向客户端发送hello $data
echo $data;
};

$worker2->onMessage = function($connection, $data)
{
// 向客户端发送hello $data
echo $data;
};

// 当有客户端连接上服务器
$worker1->onConnect = function($connection)
{
echo "new connection from ip " . $connection->getRemoteIp() . "\n";

//$inverter_s310 = new Inverter();
//$inverter_s310->setFrequency($connection,50);
};

// 当有客户端连接上服务器
$worker2->onConnect = function($connection)
{
echo "TCP new connection from ip " . $connection->getRemoteIp() . "\n";

//$inverter_s310 = new Inverter();
//$inverter_s310->setFrequency($connection,50);
};


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

--------------------------------------------------------------------------------------------------------------------------
-以上是TEST代码,但发现只有一个worker有用,另一个无法操作。
-
-

QQ截图20150706103208.png


QQ截图20150706103214.png



已邀请:

walkor

赞同来自: dahai125

上面示例中初始化了两个进程,一个是socket通讯进程,一个是websocket通讯进程,然而根据你的应用实际上是要一个Worker进程,同时支持两种通讯,这样才方便websocket与socket之间的通讯。所以根据你的实际情况,应该初始化一个同时支持两种通讯方法的Worker进程。方法如下:


<?php
use Workerman\Worker;
require_once __DIR__ . '/Workerman/Autoloader.php';
// websocket 协议的worker
$ws_worker = new Worker('Websocket://0.0.0.0:5656');
// 这里只能写1
$ws_worker->count = 1;
// websocket server 启动后在当前进程增加一个socket监听
$ws_worker->onWorkerStart = function($ws_worker)
{
// 增加一个Socket端口的监听设备发来的数据
$socket_worker = new Worker('tcp://0.0.0.0:5555');
// 当设备发来数据时如何处理
$socket_worker->onMessage = function($connection, $data)
{
// 这里处理设备发来的数据 $data
// 比如像这样给所有的WebSocket连接转发数据
global $ws_worker;
foreach($ws_worker->connections as $ws_con)
{
$ws_con->send($data);
}
};
// 给ws_worker添加一个属性保存socket_worker,方便获取
$ws_worker->socketWorker = $socket_worker;
// 执行监听
$socket_worker->listen();
};

// websocket协议也就是浏览器发来数据时
$ws_worker->onMessage = function($connection, $data)
{
// 假设需要转发给所有的设备
global $ws_worker;
foreach($ws_worker->socketWorker->connections as $socket_con)
{
$socket_con->send($data);
}
};

Worker::runAll();



上面这个例子是一个进程同时监听多协议多个端口的例子,这样socket 与 websocket之间通讯就会非常方方便,直接内存调用即可。这个例子中业务罗辑为广播,socket可以使用telnet 测试,websocket用浏览器测试,telnet与浏览器之间就可以互相通讯了,如果要针对某个特定设备推送数据,可以参考
http://wenda.workerman.net/?/question/432

最后注意尽量不要用原生tcp通讯,会有粘包问题,可以用Workerman的Text协议代替(new Worker('Text://0.0.0.0:55555')),协议规则很简单,
文本+换行符,与telnet兼容。

walkor

赞同来自:

由于widows下的php没有完善的进程控制接口,导致windows版本无法在一个启动脚本中实例化多个容器(Worker\WebServer\Gateway\BusinessWorker)进程。解决方法是使用多个启动脚本,每个脚本启动实例化一个容器。

假设初始化两个Worker实例,则创建两个启动文件 socket_server.php 和 websocket_server.php

例如:
socket_server.php

...
$socket_server = new Worker("tcp://0.0.0.0:5555");
$socket_server->on....
....

websocket_server.php

$websocket_server = new Worker("tcp://0.0.0.0:6666");
$websocket_server->on....
...


启动时就可以像这样,直接启动两个脚本,(在cmd命令行中运行)
php socket_server.php websocket_server.php

walkor

赞同来自:

相关问题:
http://wenda.workerman.net/?/question/432
http://wenda.workerman.net/?/question/421

要回复问题请先登录注册