转自:https://www.jianshu.com/p/de04ebc24bed
1.介绍
- server端会自动尝试其支持的协议,无需用户指定。(
cntl->protocol()
可获得当前协议。) - server能从一个listen端口建立不同协议的连接,不需要为不同的协议使用不同的listen端口,一个连接上也可以传输多种协议的数据包, 但一般不会这么做(也不建议)。
2.实现
在服务端接到新数据之后会调用CutInputMessage:
// src/brpc/input_messenger.cpp 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) { // _handlers中保存支持的协议配置。
//首先使用上次成功的协议解析 _handlers[preferred].parse,如果成功return;
int cur_index = preferred; do { ParseResult result = _handlers[cur_index].parse(&m->_read_buf, m, read_eof, _handlers[cur_index].arg);//按照指定协议解析 if (result.is_ok() || result.error() == PARSE_ERROR_NOT_ENOUGH_DATA) { m->set_preferred_index(cur_index);//成功后会执行set_preferred_index设置上一次使用的协议,
//这种方式不适合多个协议频繁切换的请求。 *index = cur_index; return result; } }while(true);//失败继续for循环解析,成功就找到了对应的协议,如果失败继续。 ..... }