設(shè)備連接后即立即判斷是否在線
public static function onConnect($client_id) {
$is_online = Gateway::isOnline($client_id);
file_put_contents("log11.txt", "tcp notice client_id=>" . $client_id."與服務(wù)器建立連接\r\n是否在線".$is_online."時(shí)間為".date('Y-m-d H:i:s',time())."\r\n", FILE_APPEND);
}```
當(dāng)onMessage中不發(fā)送請求時(shí)? ?均判斷正常

當(dāng)onMessage中打開post請求代碼 則出現(xiàn)剛剛 登錄設(shè)備即不在線情況,? ?在onClosez中記錄日志發(fā)現(xiàn)設(shè)備并未離線
```php
/**
* 當(dāng)客戶端發(fā)來消息時(shí)觸發(fā)
* @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進(jìn)行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);//抓取指定網(wǎng)頁
curl_setopt($ch, CURLOPT_HEADER, 0);//設(shè)置header
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);//要求結(jié)果為字符串且輸出到屏幕上
curl_setopt($ch, CURLOPT_POST, 1);//post提交方式
curl_setopt($ch, CURLOPT_POSTFIELDS, $curlPost);
$data = curl_exec($ch);//運(yùn)行curl
curl_close($ch);
return $data;
}
[attach]1573[/attach]
?
看起來應(yīng)該是業(yè)務(wù)阻塞了,導(dǎo)致進(jìn)程處理onConnect onClose事件延遲了。實(shí)際上連接確實(shí)斷開了
@614:我的這個(gè)onclose時(shí)間不是業(yè)務(wù)阻塞引起的 是設(shè)備在N次未接到參數(shù)后即自動(dòng)斷開連接
@4902: 自動(dòng)斷開? 在N次沒有接收到消息后,是服務(wù)端主動(dòng)關(guān)閉設(shè)備連接還是客戶端主動(dòng)關(guān)閉了設(shè)備連接?
@4902:
1、問題原因找到了嗎或者解決了嗎?
2、我模擬了針對API的各種超時(shí)以及業(yè)務(wù)阻塞的場景,均未能重現(xiàn)你說的這種情況。
3、根據(jù)老大說的原因,onConnect、onClose事件可能延遲了,進(jìn)程在此之前有大量的業(yè)務(wù)邏輯阻塞?
4、建議你抓下包看下具體發(fā)生了什么,調(diào)試下 isOnline() 代碼也可以。
我是php的初級工作者 可能有一些理解和描述并不正確,然后我跟您描述一下
1.我們這是一個(gè)物聯(lián)網(wǎng)項(xiàng)目,可類似理解為共享單車,設(shè)備(以下類比簡稱為車)會不間斷的發(fā)送各種消息過來,包括登錄簽到,心跳,訂單數(shù)據(jù)等,服務(wù)器需要回復(fù)這些請求.當(dāng)?shù)卿浐灥交蛘咝奶腥螞]有回復(fù)時(shí),車自動(dòng)斷開連接,重連
2.因?yàn)榘凑誫atewaywoker文檔要求分離部署mvc和wokerman,而車是通過tcp方式連接,無法通過訪問url下接口的方式發(fā)送數(shù)據(jù)給MVC,我在onmessage中使用curl將數(shù)據(jù)post將數(shù)據(jù)發(fā)送到MVC中等待返回?cái)?shù)據(jù),然后再將數(shù)據(jù)返回給車
3.在發(fā)送給MVC的數(shù)據(jù)中有一些數(shù)據(jù)處理比較復(fù)雜,大概需要2-3秒的時(shí)間才能返回?cái)?shù)據(jù),當(dāng)有一個(gè)請求post 出去等待返回?cái)?shù)據(jù)的時(shí)候,其他的消息被阻塞了,比如車在第10秒發(fā)送了心跳的消息,而第30秒才輪到這個(gè)消息post到mvc中,當(dāng)返回消息時(shí)車已經(jīng)發(fā)送了3次心跳斷開了連接,以此類推服務(wù)運(yùn)行的時(shí)間越長,接到的數(shù)據(jù)就越延遲,而至于為什么onconnect接收消息也發(fā)生了延遲我就不太特別清楚了
4.我在windows環(huán)境下跑的當(dāng)時(shí)看了文檔想通過start.php status看看什么情況的 結(jié)果只能linux下看好像,也可能是我不會用,最后我們起了一個(gè)java的服務(wù)接收數(shù)據(jù)發(fā)送給mvc解決了這個(gè)
以上
@614:另外當(dāng)時(shí)我做了一下嘗試
1.將數(shù)據(jù)放到redis中,然后循環(huán)讀取隊(duì)列消息發(fā)送到MVC中,onconnect中與onclose中連接與斷開恢復(fù)正常,但是依然在post數(shù)據(jù)時(shí)因?yàn)樽枞脑蛳⒒貜?fù)出現(xiàn)延遲,設(shè)備無法保持連接.
2.使用了AsyncTcpConnection類進(jìn)行異步請求,但是文檔范例中并沒有寫怎么攜帶參數(shù),可能我比較菜.......我通過拼接url的方式進(jìn)行了get請求格式如下(www.xxx.com/Index/xxx?ip=xxxxx&data=xxxx),但是好像連AsyncTcpConnection的onConnect 都無法進(jìn)入,具體什么情況忘記了
3.使用了文檔中http-client如上拼接url進(jìn)行異步請求,一部分可以請求成功,有一部分?jǐn)?shù)據(jù)進(jìn)入到error區(qū)間,記錄了$e但是看不懂...也放棄了
然后項(xiàng)目確實(shí)著急就讓同事搭了java的一套TCP
今天其實(shí)又找了一段異步請求的代碼,但是因?yàn)闇y試的車都連到了現(xiàn)在的JAVA上面趕項(xiàng)目也沒辦法進(jìn)行測試,不過好像沒辦法這個(gè)沒辦法接到返回值,打算再用一下朋友推薦的Guzzle,雖然java的同事搞定了這部分,但是自己的問題其實(shí)沒解決有點(diǎn)心里抓的慌.......
以上
@4902:
1、看了一下,明顯的第3條這里就是業(yè)務(wù)阻塞的場景,正是因?yàn)樽枞瑢?dǎo)致你說的服務(wù)端回復(fù)延遲,所以有些客戶端事實(shí)上在此之前已經(jīng)斷開了。
2、要是我的話,果斷選擇典型異步任務(wù)模型來搞,即使用 AsyncTcpConnection()將這些耗時(shí)的任務(wù)轉(zhuǎn)發(fā)給后端的集群任務(wù)進(jìn)程來處理。
3、使用 AsyncTcpConnection 可以發(fā)送任何協(xié)議支持的數(shù)據(jù),這個(gè)數(shù)據(jù)即send()函數(shù)的參數(shù),自己拼接就行。
@614:大佬是否可以提供一個(gè)發(fā)送http post數(shù)據(jù)的AsyncTcpConnection簡單例子代碼呢? 我不太懂看了看也沒拼出來
@4902: 這個(gè)官方就有現(xiàn)成的例子代碼:http://doc.workerman.net/faq/async-task.html, 你要做的基于http post 的,只需啟動(dòng)一個(gè) http woker即可,比如例子中 "任務(wù)進(jìn)程服務(wù)端" 保持不變【除非你換用其他的協(xié)議】,將調(diào)用端的websocket woker 改為 http worker即可, 這樣設(shè)備就可以: http post ---> http worker ---> proxy async ---> task worker