server端会自动尝试其支持的协议,无需用户指定。(
cntl->protocol()
可获得当前协议。)
server能从
一个listen端口
建立不同协议的连接,不需要为不同的协议使用不同的listen端口,一个连接上也可以传输多种协议的数据包, 但一般不会这么做(也不建议)。
在服务端接到新数据之后会调用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;
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循环解析,成功就找到了对应的协议,如果失败继续。
.....