设备连接后即立即判断是否在线
public static function onConnect($client_id) {
$is_online = Gateway::isOnline($client_id);
file_put_contents("log11.txt", "tcp notice client_id=>" . $client_id."与服务器建立连接\r\n是否在线".$is_online."时间为".date('Y-m-d H:i:s',time())."\r\n", FILE_APPEND);
}```
当onMessage中不发送请求时 均判断正常
![图片](//www.workerman.net/upload/questions/20181220/990d220515c93d8413c12e64cad88000.jpg)
当onMessage中打开post请求代码 则出现刚刚 登录设备即不在线情况, 在onClosez中记录日志发现设备并未离线
```php
/**
* 当客户端发来消息时触发
* @param int $client_id 连接id
* @param mixed $message 具体消息
*/
public static function onMessage($client_id, $message) {
$message = bin2hex($message);
$match = str_split($message,2);
$message = implode(' ', $match);
$uid = str_replace('.', "_",$_SERVER).'_'.$_SERVER;
$order_info = array(
'ip'=>$uid,
'data'=>$message,
);
// $result =
self::http_post('xxx.xxx.cn/WXAPI/Workerman/Charge_api',$order_info);
}
/**
* 模拟post进行url请求
* @param string $url
* @param array $post_data
*/
public static function http_post($url = '', $post_data = array()) {
if (empty($url) || empty($post_data)) {
return false;
}
$o = "";
foreach ( $post_data as $k => $v )
{
$o.= "$k=" . urlencode( $v ). "&" ;
}
$post_data = substr($o,0,-1);
$postUrl = $url;
$curlPost = $post_data;
$ch = curl_init();//初始化curl
curl_setopt($ch, CURLOPT_URL,$postUrl);//抓取指定网页
curl_setopt($ch, CURLOPT_HEADER, 0);//设置header
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);//要求结果为字符串且输出到屏幕上
curl_setopt($ch, CURLOPT_POST, 1);//post提交方式
curl_setopt($ch, CURLOPT_POSTFIELDS, $curlPost);
$data = curl_exec($ch);//运行curl
curl_close($ch);
return $data;
}
运行一会后则判断所有进入的连接都为不在线
代码看上去似乎没有问题,建议你抓包看下是谁主动关闭了连接。
linux服务器?阿里云?是否有加负载均衡?
onClose里记录日志到 log11.txt,有问题后再截图log11.txt内容。
windows服务器.........
您的意思是被阻塞了么?
我有单独记录连接和断开的日志 马上贴上来
[attach]1573[/attach]
如上 当刚刚建立连接时即判断为不在线,但是onclose事件在几十秒后才被触发
看起来应该是业务阻塞了,导致进程处理onConnect onClose事件延迟了。实际上连接确实断开了
@614:我的这个onclose时间不是业务阻塞引起的 是设备在N次未接到参数后即自动断开连接
@4902: 自动断开? 在N次没有接收到消息后,是服务端主动关闭设备连接还是客户端主动关闭了设备连接?
@614:客户端
@4902:
1、问题原因找到了吗或者解决了吗?
2、我模拟了针对API的各种超时以及业务阻塞的场景,均未能重现你说的这种情况。
3、根据老大说的原因,onConnect、onClose事件可能延迟了,进程在此之前有大量的业务逻辑阻塞?
4、建议你抓下包看下具体发生了什么,调试下 isOnline() 代码也可以。
我是php的初级工作者 可能有一些理解和描述并不正确,然后我跟您描述一下
1.我们这是一个物联网项目,可类似理解为共享单车,设备(以下类比简称为车)会不间断的发送各种消息过来,包括登录签到,心跳,订单数据等,服务器需要回复这些请求.当登录签到或者心跳有三次没有回复时,车自动断开连接,重连
2.因为按照gatewaywoker文档要求分离部署mvc和wokerman,而车是通过tcp方式连接,无法通过访问url下接口的方式发送数据给MVC,我在onmessage中使用curl将数据post将数据发送到MVC中等待返回数据,然后再将数据返回给车
3.在发送给MVC的数据中有一些数据处理比较复杂,大概需要2-3秒的时间才能返回数据,当有一个请求post 出去等待返回数据的时候,其他的消息被阻塞了,比如车在第10秒发送了心跳的消息,而第30秒才轮到这个消息post到mvc中,当返回消息时车已经发送了3次心跳断开了连接,以此类推服务运行的时间越长,接到的数据就越延迟,而至于为什么onconnect接收消息也发生了延迟我就不太特别清楚了
4.我在windows环境下跑的当时看了文档想通过start.php status看看什么情况的 结果只能linux下看好像,也可能是我不会用,最后我们起了一个java的服务接收数据发送给mvc解决了这个
以上
@614:另外当时我做了一下尝试
1.将数据放到redis中,然后循环读取队列消息发送到MVC中,onconnect中与onclose中连接与断开恢复正常,但是依然在post数据时因为阻塞的原因消息回复出现延迟,设备无法保持连接.
2.使用了AsyncTcpConnection类进行异步请求,但是文档范例中并没有写怎么携带参数,可能我比较菜.......我通过拼接url的方式进行了get请求格式如下(www.xxx.com/Index/xxx?ip=xxxxx&data=xxxx),但是好像连AsyncTcpConnection的onConnect 都无法进入,具体什么情况忘记了
3.使用了文档中http-client如上拼接url进行异步请求,一部分可以请求成功,有一部分数据进入到error区间,记录了$e但是看不懂...也放弃了
然后项目确实着急就让同事搭了java的一套TCP
今天其实又找了一段异步请求的代码,但是因为测试的车都连到了现在的JAVA上面赶项目也没办法进行测试,不过好像没办法这个没办法接到返回值,打算再用一下朋友推荐的Guzzle,虽然java的同事搞定了这部分,但是自己的问题其实没解决有点心里抓的慌.......
以上
@4902:
1、看了一下,明显的第3条这里就是业务阻塞的场景,正是因为阻塞,导致你说的服务端回复延迟,所以有些客户端事实上在此之前已经断开了。
2、要是我的话,果断选择典型异步任务模型来搞,即使用 AsyncTcpConnection()将这些耗时的任务转发给后端的集群任务进程来处理。
3、使用 AsyncTcpConnection 可以发送任何协议支持的数据,这个数据即send()函数的参数,自己拼接就行。
@614:大佬是否可以提供一个发送http post数据的AsyncTcpConnection简单例子代码呢? 我不太懂看了看也没拼出来
@4902: 这个官方就有现成的例子代码:http://doc.workerman.net/faq/async-task.html, 你要做的基于http post 的,只需启动一个 http woker即可,比如例子中 "任务进程服务端" 保持不变【除非你换用其他的协议】,将调用端的websocket woker 改为 http worker即可, 这样设备就可以: http post ---> http worker ---> proxy async ---> task worker