gatewayworker如何实现硬件设备tcp与浏览器websocket互相通讯

0

已邀请:

walkor

赞同来自: lwy

GatewayWorker所有的数据通过Events.php里的onMessage来接收。


gatewayWorker支持多协议,如果增加一个协议只需要开一个端口设置对应的端口参数及协议即可。协议层对于开发者来说是透明的。也就是说调用所有的gatewayWorker 的 Gateway::XXX(如Gateway::bindUid Gateway::sendToUid)接口时,不需要考虑对应客户端是什么协议,直接调用即可。


如何设置多个协议,参考http://doc2.workerman.net/multi-protocols.html


现在假设你设置了tcp协议和websocket协议。那么整个系统代码及流程类似这样


1)、硬件客户端通过tcp向GatewayWorker发送一个数据包,包中包含了{请求类型:设备绑定, 设备id:设备具体id}(数据格式任意,这里是一个示意),GatewayWorker收到数据后,Events.php里的onMessage接收整个数据,发现是设备绑定类型,然后调用Gateway::bindUid($client_id, '具体的设备id');,这样就将设备于具体的设备id绑定了,在Events.php中调用Gateway::sendToUid('具体的设备id', '数据');就可以给这个设备发数据了。


2)、同样的用户端通过websocket发起连接,然后发送一个{请求类型:用户绑定, 用户id:用户具体id}请求给GatewayWorker,Events.php里的onMessage接收整个数据,发现是用户绑定类型,然后调用Gateway::bindUid($client_id, '具体的用户id');,这样就将用户端与具体的用户id绑定了,在Events.php中调用Gateway::sendToUid('具体用户id', '数据');就可以给这个用户发数据了。


假设你上面的设备及用户绑定已经做好,现在说说你的图中1 2 3 4 5 6的代码及流程
1、设备发起tcp请求
假设请求数据格式为 {type: getData}


2、GatewayWorker收到tcp请求后返回该设备相关数据
给当前设备返回数据,直接调用 Gateway::sendToClient($client_id, '数据');即可。


3、用户通过websocket发送开关指令
假设数据格式为 {type: opertation, operation: close, device_id:具体设备id}


4、服务端收到指令后发给设备
Events.php里onMessage里利用Gateway::sendToUid(具体设备id, '设备能识别的关闭数据');给对应设备发送操作


5、设备返回成功或失败
数据包假设格式为{type: opertation_result, result: success},同样的Events.php里onMessage里接收这个数据


6、将成功或者失败结果转发给用户
Events.php里onMessage里利用Gateway::sendToUid(具体用户id, '结果数据');给对应的用户id


总的来说Events.php里代码类似这样。
假设设备和用户发来的数据都是json数据,代码类似这样


class Events {
public static function onMessage ($client_id, $data)
{
$data = json_decode($data);
switch ($data['type']) {

// {type:device_bind, device_id:具体的设备id}
case 'device_bind':
Gateway::bindUid($client_id, $data['device_id']);
// 通过数据库或则某种方式查询出当前设备属于哪个用户,并记录到session方便后面直接使用
$user_id = your_find_user_function($data['device_id']);
$_SESSION['belong'] = $user_id;
break;

// {type:device_bind, user_id:具体的用户id}
case 'user_bind':
Gateway::bindUid($client_id, $data['user_id']);
break;

case 'getData':
$getDataResult = '结果数据'; // 这里假设获得了结果
Gateway::sendToClient($client_id, $getDataResult);
break;

// {type: opertation, operation: close, device_id:具体设备id}
case 'operation':
Gateway::sendToUid($data['device_id'], "{type: opertation, operation: close}");
break;

// {type: opertation_result, result: success}
case 'opertation_result':
// 之前在sessin中记录了当前设备属于哪个用户
$user_id = $_SESSION['belong'];
// 给这个用户发送结果
Gateway::sendToUid($uiser_id, "{type: opertation_result, result: success}");
break;
}
}
}

敖德萨

赞同来自: yeeser

好的谢谢 已经解决了 谢谢提供思路和解法

taozywu - http://www.athanb.com

赞同来自:

@敖德萨
1)用户端建立websocket通信
2)硬件端建立tcp通信
3)通过$_SERVER['REMOTE_PORT']和$_SERVER['REMOTE_ADDR']来区分过来的数据
4)每个端数据中传一个相同参数作为互推依据。

敖德萨

赞同来自:

可以给个具体方案吗?你说通过$_SERVER['REMOTE_PORT']和$_SERVER['REMOTE_ADDR']来区分发过来的数据 那么问题来了 我在哪里接收?onmessge? onmessge怎样接收tcp协议发过来的数据?这个也是现在困扰我的问题 所以你说了这么多 我还没看到有希望的信息 能给个具体的信息吗

yeeser

赞同来自:

您好,您的思路和解法可以给我发一份吗?谢谢

敖德萨

赞同来自:

@walkor大佬已经给了解决的方法了 业务在Events.php中处理即可 这没有什么逻辑思路的

要回复问题请先登录注册