brpc 多協(xié)議解析處理

server端會(huì)自動(dòng)嘗試其支持的協(xié)議舌厨,無(wú)需用戶(hù)指定。cntl->protocol()可獲得當(dāng)前協(xié)議夭问。server能從一個(gè)listen端口建立不同協(xié)議的連接烛卧,不需要為不同的協(xié)議使用不同的listen端口佩微,一個(gè)連接上也可以傳輸多種協(xié)議的數(shù)據(jù)包, 但一般不會(huì)這么做(也不建議)缝彬。

下面分析一下這部分實(shí)現(xiàn):
在服務(wù)端接到新數(shù)據(jù)之后會(huì)調(diào)用CutInputMessage。

_handlers中保存支持的協(xié)議配置哺眯。

首先使用上次成功的協(xié)議解析 _handlers[preferred].parse谷浅,如果成功return;
如果失敗繼續(xù)for循環(huán)解析族购,成功就找到了對(duì)應(yīng)的協(xié)議壳贪,如果失敗繼續(xù)陵珍。

成功后會(huì)執(zhí)行set_preferred_index設(shè)置上一次使用的協(xié)議寝杖,這種方式不適合多個(gè)協(xié)議頻繁切換的請(qǐng)求。

ParseResult InputMessenger::CutInputMessage(
        Socket* m, size_t* index, bool read_eof) {
    const int preferred = m->preferred_index();
    const int max_index = (int)_max_index.load(butil::memory_order_acquire);
    // Try preferred handler first. The preferred_index is set on last
    // selection or by client.
    if (preferred >= 0 && preferred <= max_index
            && _handlers[preferred].parse != NULL) {
        ParseResult result =
            _handlers[preferred].parse(&m->_read_buf, m, read_eof, _handlers[preferred].arg);
        if (result.is_ok() ||
            result.error() == PARSE_ERROR_NOT_ENOUGH_DATA) {
            *index = preferred;
            return result;
        } else if (result.error() != PARSE_ERROR_TRY_OTHERS) {
            // Critical error, return directly.
            LOG_IF(ERROR, result.error() == PARSE_ERROR_TOO_BIG_DATA)
                << "A message from " << m->remote_side()
                << "(protocol=" << _handlers[preferred].name
                << ") is bigger than " << FLAGS_max_body_size
                << " bytes, the connection will be closed."
                " Set max_body_size to allow bigger messages";
            return result;
        }
        if (m->CreatedByConnect() &&
            // baidu_std may fall to streaming_rpc
            (ProtocolType)preferred != PROTOCOL_BAIDU_STD) {
            // The protocol is fixed at client-side, no need to try others.
            LOG(ERROR) << "Fail to parse response from " << m->remote_side()
                       << " by " << _handlers[preferred].name 
                       << " at client-side";
            return MakeParseError(PARSE_ERROR_ABSOLUTELY_WRONG);
        }
        // Clear context before trying next protocol which probably has
        // an incompatible context with the current one.
        if (m->parsing_context()) {
            m->reset_parsing_context(NULL);
        }
        m->set_preferred_index(-1);
    }
    for (int i = 0; i <= max_index; ++i) {
        if (i == preferred || _handlers[i].parse == NULL) {
            // Don't try preferred handler(already tried) or invalid handler
            continue;
        }
        ParseResult result = _handlers[i].parse(&m->_read_buf, m, read_eof, _handlers[i].arg);
        if (result.is_ok() ||
            result.error() == PARSE_ERROR_NOT_ENOUGH_DATA) {
            m->set_preferred_index(i);
            *index = i;
            return result;
        } else if (result.error() != PARSE_ERROR_TRY_OTHERS) {
            // Critical error, return directly.
            LOG_IF(ERROR, result.error() == PARSE_ERROR_TOO_BIG_DATA)
                << "A message from " << m->remote_side()
                << "(protocol=" << _handlers[i].name
                << ") is bigger than " << FLAGS_max_body_size
                << " bytes, the connection will be closed."
                " Set max_body_size to allow bigger messages";
            return result;
        }
        // Clear context before trying next protocol which definitely has
        // an incompatible context with the current one.
        if (m->parsing_context()) {
            m->reset_parsing_context(NULL);
        }
        // Try other protocols.
    }
    return MakeParseError(PARSE_ERROR_TRY_OTHERS);
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末互纯,一起剝皮案震驚了整個(gè)濱河市瑟幕,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌留潦,老刑警劉巖只盹,帶你破解...
    沈念sama閱讀 207,248評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異兔院,居然都是意外死亡殖卑,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門(mén)坊萝,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)孵稽,“玉大人,你說(shuō)我怎么就攤上這事十偶∑邢剩” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 153,443評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵惦积,是天一觀(guān)的道長(zhǎng)接校。 經(jīng)常有香客問(wèn)我,道長(zhǎng)狮崩,這世上最難降的妖魔是什么蛛勉? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,475評(píng)論 1 279
  • 正文 為了忘掉前任鹿寻,我火速辦了婚禮,結(jié)果婚禮上诽凌,老公的妹妹穿的比我還像新娘烈和。我一直安慰自己,他們只是感情好皿淋,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,458評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布招刹。 她就那樣靜靜地躺著,像睡著了一般窝趣。 火紅的嫁衣襯著肌膚如雪疯暑。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,185評(píng)論 1 284
  • 那天哑舒,我揣著相機(jī)與錄音妇拯,去河邊找鬼。 笑死洗鸵,一個(gè)胖子當(dāng)著我的面吹牛越锈,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播膘滨,決...
    沈念sama閱讀 38,451評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼甘凭,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了火邓?” 一聲冷哼從身側(cè)響起丹弱,我...
    開(kāi)封第一講書(shū)人閱讀 37,112評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎铲咨,沒(méi)想到半個(gè)月后躲胳,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,609評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡纤勒,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,083評(píng)論 2 325
  • 正文 我和宋清朗相戀三年坯苹,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片摇天。...
    茶點(diǎn)故事閱讀 38,163評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡粹湃,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出闸翅,到底是詐尸還是另有隱情再芋,我是刑警寧澤,帶...
    沈念sama閱讀 33,803評(píng)論 4 323
  • 正文 年R本政府宣布坚冀,位于F島的核電站济赎,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜司训,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,357評(píng)論 3 307
  • 文/蒙蒙 一构捡、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧壳猜,春花似錦勾徽、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,357評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至咒钟,卻和暖如春吹由,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背朱嘴。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,590評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工倾鲫, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人萍嬉。 一個(gè)月前我還...
    沈念sama閱讀 45,636評(píng)論 2 355
  • 正文 我出身青樓乌昔,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親壤追。 傳聞我的和親對(duì)象是個(gè)殘疾皇子磕道,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,925評(píng)論 2 344

推薦閱讀更多精彩內(nèi)容