在項(xiàng)目中我在events.php中來(lái)try catch錯(cuò)誤
public static function onMessage($client_id, $message)
{
try {
$message = json_decode($message, true);
if (!is_array($message))
return Gateway::sendToCurrentClient(self::error(400, '參數(shù)類(lèi)型錯(cuò)誤'));
if ($message['type'] > 1000 and !isset($_SESSION['member_id'])) {
return Gateway::closeClient($client_id, self::error(400, '未登錄'));
}
switch ($message['type']) {
case interview_admin_bind:
InterviewService::admin_bind($client_id, $message);
case bind:
MemberService::bind($client_id, $message);
break;
default :
return Gateway::sendToCurrentClient(self::success(1));
break;
}
} catch (Throwable $exception) {
var_dump($exception->getMessage());
var_dump($exception->getTrace());
if ($exception instanceof MyException) {
return Gateway::sendToCurrentClient(self::error($exception->type, $exception->getMessage(), $exception->getCode(), $exception->data));
} else {
return Gateway::sendToCurrentClient(self::error(400, $exception->getMessage()));
}
}
}
例如這樣我來(lái)捕捉異常,但是notice錯(cuò)誤捕獲不了
即使開(kāi)啟了嚴(yán)格模式也不行,
declare(strict_types=1);
請(qǐng)問(wèn)一下怎么才能讓這個(gè)notice被try catch捕獲到,因?yàn)槲蚁肴魏吻闆r下出現(xiàn)了任何錯(cuò)誤,不論級(jí)別都走異常處理
想到一種解決辦法就是自定義
set_error_handler方法來(lái)拋出異常
這樣是能正確拋出異常的,把Notice錯(cuò)誤弄成自定義的Exception異常
但是有一個(gè)問(wèn)題就是 Crtl + C 退出的時(shí)候報(bào)了一堆錯(cuò)誤
求解
還有一個(gè)這個(gè)報(bào)錯(cuò),這個(gè)影響嗎?
主要問(wèn)題還是
\set_error_handler(function ($type, $msg) {
var_dump($type, $msg);
throw new MyException(400, $msg);
}, E_NOTICE);
這一句,雖然游泳,但是onClose的時(shí)候,因?yàn)槲矣幸恍?shù)據(jù)是卸載redis和db中的,無(wú)論用戶(hù)觸發(fā)的onClose還是我中斷Ctrl+C退出,都監(jiān)聽(tīng)了onClose回調(diào),去處理一些數(shù)據(jù),所以如果報(bào)錯(cuò)的話(huà)就不應(yīng)該,怎樣順滑的去處理那個(gè)報(bào)錯(cuò)呢?
看追蹤是
斷開(kāi)鏈接>用戶(hù)離開(kāi)group>給group發(fā)送消息(有用戶(hù)離開(kāi)) 就是這一步發(fā)消息出現(xiàn)的問(wèn)題
//監(jiān)聽(tīng)onClose
public static function onClose($client_id)
{
InterviewService::leave($client_id);
}
//用戶(hù)離開(kāi)的方法,去處理redis中的數(shù)據(jù)
public static function leave($client_id)
{
$interview_id = $_SESSION['interview_join'];
unset($_SESSION['interview_join']);
$room_key = "interview_room|id:$interview_id";
$interview = Rdb::getInstance()->get($room_key, false);
$interview = json_decode($interview, true);
//*******doSomeThing
Rdb::getInstance()->set($room_key, $interview, 18000);
Gateway::leaveGroup($client_id, $room_key);
Gateway::sendToGroup($room_key, self::success(interview_update, $interview));
Gateway::sendToGroup($room_key, self::success(interview_member_leave, $member));
}
報(bào)錯(cuò)信息就是在sendToGroup這一步出現(xiàn)的,主要還是開(kāi)啟了那個(gè)set_error_handler方法,如果不設(shè)置set_error_handler就不會(huì)報(bào)錯(cuò),求解啊。
還有只有服務(wù)端Ctrl + C 關(guān)閉服務(wù)才會(huì)報(bào)錯(cuò),用戶(hù)端主動(dòng)調(diào)用leave方法或者用戶(hù)端直接斷開(kāi)socket鏈接就不報(bào)錯(cuò)。?。。?/code>
想到一個(gè)解決辦法,既然是onClose里面調(diào)用了sendGroup方法報(bào)的錯(cuò)。
用戶(hù)端斷開(kāi)鏈接我肯定要通知group里面的人,所以用senfGroup方法沒(méi)問(wèn)題也不會(huì)報(bào)錯(cuò)。
然后我服務(wù)端關(guān)閉服務(wù)用sendGroup方法會(huì)報(bào)錯(cuò),但是我服務(wù)端其實(shí)主要是處理邏輯就行了,不需要用到sendGroup方法,不需要給用戶(hù)發(fā)消息,把邏輯處理完就行了。
那么有沒(méi)有辦法判斷是用戶(hù)觸發(fā)的onClose還是服務(wù)端Ctrl + C 觸發(fā)的onClose呢?
要是能判斷到服務(wù)端觸發(fā)的onClose,那么我就不sendGroup不就行了?
walkor大佬解答一下?
或者說(shuō)還是set_error_handler方法用錯(cuò)了?
我覺(jué)得好像后面這個(gè)辦法好一點(diǎn),判斷服務(wù)端還是客服端觸發(fā)的onClose更好
ctrl c 停止過(guò)程中的報(bào)錯(cuò)可以忽略吧。因?yàn)間ateway進(jìn)程可能都沒(méi)了,然后還執(zhí)行業(yè)務(wù)就報(bào)錯(cuò)了。
因?yàn)槲矣幸徊糠謹(jǐn)?shù)據(jù)寫(xiě)在redis中的,在onClose中需要去處理一下, 當(dāng)然你說(shuō)的也有道理,進(jìn)程都沒(méi)了,其實(shí)處不處理不重要了,但是現(xiàn)在遇到了報(bào)錯(cuò)肯定要想辦法解決啊,身為一個(gè)程序員的操守 哈哈哈