WebServer icon indicating copy to clipboard operation
WebServer copied to clipboard

管线化

Open fanjinhua opened this issue 4 years ago • 10 comments

管线化实现在哪部分啊,怎么实现的?

fanjinhua avatar Jul 05 '19 16:07 fanjinhua

@fanjinhua 没有专门的实现,整个收发流程天生支持

linyacool avatar Jul 05 '19 16:07 linyacool

所以是客户端决定是否发起管线化请求,http1.1 服务器天然支持管线化请求(基于长连接)。

fanjinhua avatar Jul 06 '19 02:07 fanjinhua

@fanjinhua 可以这么理解

linyacool avatar Jul 06 '19 14:07 linyacool

@fanjinhua 可以这么理解

大佬,我不明白这个地方为什么你们说服务器端收发流程天生支持管线化。如果客户端那边支持并发起管线化请求的话,数个请求会通过一个TCP连接发过来,但服务端的代码中并没有把这些请求分开的操作,这在http1.1中不是会引起混乱吗? 您能给说下为什么不会被影响吗?

sirenscat avatar Oct 14 '19 12:10 sirenscat

没有完全理解。http1.1确实天然支持管线化,但您的服务器并没有直接使用http1.1吧

Joker1937 avatar Aug 10 '21 03:08 Joker1937

http1.1 是个协议,不是使不使用,是要去实现的东西

linyacool avatar Aug 10 '21 03:08 linyacool

既然需要自己实现那具体这部分代码在哪里体现呢?

Joker1937 avatar Aug 10 '21 04:08 Joker1937

@fanjinhua 可以这么理解

大佬,我不明白这个地方为什么你们说服务器端收发流程天生支持管线化。如果客户端那边支持并发起管线化请求的话,数个请求会通过一个TCP连接发过来,但服务端的代码中并没有把这些请求分开的操作,这在http1.1中不是会引起混乱吗? 您能给说下为什么不会被影响吗?

这一段在HttpData.cpp的代码应该是管线化,一个完整的请求解析完后,就发送出去,如果接收缓冲还有数据(inbuff.szie()>0),说明还有请求,reset将状态设为STATE_PARSE_URI,继续handleRead()进行解析。我是这么理解的 do{ if (state_ == STATE_PARSE_URI) { ... } if (state_ == STATE_PARSE_HEADERS) { ... } if (method_ == METHOD_POST) { // POST方法准备 state_ = STATE_RECV_BODY; } else { state_ = STATE_ANALYSIS; } } if (state_ == STATE_RECV_BODY) { ... } if (state_ == STATE_ANALYSIS) { ... } } while (false);

if (!error_) { if (outBuffer_.size() > 0) { handleWrite(); // events_ |= EPOLLOUT; } // error_ may change if (!error_ && state_ == STATE_FINISH) { this->reset(); if (inBuffer_.size() > 0) { if (connectionState_ != H_DISCONNECTING) handleRead(); } } }

sunyuanfeng1 avatar Aug 22 '21 06:08 sunyuanfeng1

既然需要自己实现那具体这部分代码在哪里体现呢?

HttpData中的解析就是实现啊

sunyuanfeng1 avatar Aug 22 '21 06:08 sunyuanfeng1

@fanjinhua 可以这么理解

大佬,我不明白这个地方为什么你们说服务器端收发流程天生支持管线化。如果客户端那边支持并发起管线化请求的话,数个请求会通过一个TCP连接发过来,但服务端的代码中并没有把这些请求分开的操作,这在http1.1中不是会引起混乱吗? 您能给说下为什么不会被影响吗?

这一段在HttpData.cpp的代码应该是管线化,一个完整的请求解析完后,就发送出去,如果接收缓冲还有数据(inbuff.szie()>0),说明还有请求,reset将状态设为STATE_PARSE_URI,继续handleRead()进行解析。我是这么理解的 do{ if (state_ == STATE_PARSE_URI) { ... } if (state_ == STATE_PARSE_HEADERS) { ... } if (method_ == METHOD_POST) { // POST方法准备 state_ = STATE_RECV_BODY; } else { state_ = STATE_ANALYSIS; } } if (state_ == STATE_RECV_BODY) { ... } if (state_ == STATE_ANALYSIS) { ... } } while (false);

if (!error_) { if (outBuffer_.size() > 0) { handleWrite(); // events_ |= EPOLLOUT; } // error_ may change if (!error_ && state_ == STATE_FINISH) { this->reset(); if (inBuffer_.size() > 0) { if (connectionState_ != H_DISCONNECTING) handleRead(); } } }

同意,这部分状态机的实现其实就包含了拆包了,接收到的数据放到buffer中,buffer中并不一定只有一次请求的数据,但是在处理buffer中的数据时会按照格式只处理一个请求的数据,剩余的数据属于下一个请求了,还会再执行一遍状态机的流程。

CNLarryAn avatar Jan 20 '22 12:01 CNLarryAn