Peer类是用于描述用户连接的。在Pistache 并发处理过程中指出,Pistache中,有一个专门的线程负责监听server-fd,并accept用户的连接产生client-fd,然后将client-fd派发给处理线程去监听、解析、处理和返回数据。而peer类就是用于描述用户连接的结构,每个用户连接对应于一个Peer对象。
下为Peer类的结构:
class Peer
{
public:
friend class Transport;
friend class Http::Handler;
friend class Http::Timeout;
~Peer();
static std::shared_ptr<Peer> Create(Fd fd, const Address& addr);
static std::shared_ptr<Peer> CreateSSL(Fd fd, const Address& addr, void* ssl);
const Address& address() const;
const std::string& hostname();
Fd fd() const;
void* ssl() const;
void putData(std::string name, std::shared_ptr<void> data);
std::shared_ptr<void> getData(std::string name) const;
std::shared_ptr<void> tryGetData(std::string name) const;
Async::Promise<ssize_t> send(const RawBuffer& buffer, int flags = 0);
size_t getID() const;
protected:
Peer(Fd fd, const Address& addr, void* ssl);
private:
void associateTransport(Transport* transport);
Transport* transport() const;
static size_t getUniqueId();
Transport* transport_ = nullptr;
Fd fd_ = -1;
Address addr;
std::string hostname_;
std::unordered_map<std::string, std::shared_ptr<void>> data_;
void* ssl_ = nullptr;
const size_t id_;
};
成员变量
private
-
Transport* transport_ = nullptr
Transport中实现了对请求(request)和响应(response)的封装,是一个贯穿整个请求处理流程的结构,在Peer中,主要用于实现send接口,Transport封装了异步的写接口,用于向网络中异步的发送数据 -
Fd fd_ = -1
用于记录用户连接的client-fd,需要被添加到poller中,被处理线程监听,等待用户的http请求并处理 -
Address addr
用于存放用户连接的地址信息,Address封装了socket地址,包括了IP和port等信息。 -
std::string hostname_
通过getnameinfo()方法获取的主机名 -
std::unordered_map<std::string, std::shared_ptr<void>> data_
unordered_map是基于hash表实现的"无序"映射,而map是基于红黑树的有序映射,前者在查找速度上有优势。
data_,用于存放peer的特定数据,在实现上,目前是用来存放Request结构的。每当创建连接时,初始化一个Request结构,将其指针放入peer.data_中。当接受到http请求时,从peer中取出request,并解析http数据到request中,最后将request作为参数,传递给用户的处理函数。 -
void* ssl_ = nullptr
ssl 相关,我对网络的理解目前还没涉及到ssl,所以相关的内容都跳过,pitache默认也未使用ssl -
const size_t id_
唯一标识
构造函数
protected:
Peer::Peer(Fd fd, const Address& addr, void* ssl)
: fd_(fd)
, addr(addr)
, ssl_(ssl)
, id_(getUniqueId())
{ }
成员函数
private
-
void associateTransport(Transport* transport);
用于指定transport_
的值,在创建peer后,会为peer指定具体的执行的线程,每个线程和一个transport对象绑定,associateTransport()实现peer和transport的绑定。 -
Transport* transport() const;
返回与peer绑定的transport,若为空,则throw错误。 -
static size_t getUniqueId();
返回唯一的peer ID,此ID是原子静态变量,每调用自增一次,可以记录peer的创建个数。
public
static std::shared_ptr<Peer> Create(Fd fd, const Address& addr);
-
static std::shared_ptr<Peer> CreateSSL(Fd fd, const Address& addr, void* ssl);
用于创建Peer对象的函数,返回的是shared_ptr智能指针。 const Address& address() const;
const std::string& hostname();
Fd fd() const;
void* ssl() const;
-
size_t getID() const;
getter函数,其中hostname()比较特殊,如果addr.host
字段本身就是host主机名字符串,那么将直接将其赋值给hostname_
,否则,需要使用getnameinfo()来检索主机名,如果检索失败,则赋值为空字符串。 void putData(std::string name, std::shared_ptr<void> data);
std::shared_ptr<void> getData(std::string name) const;
-
std::shared_ptr<void> tryGetData(std::string name) const;
用于操作data_
,如果在已经存在name的情况下调用putData或者在不存在name的情况下调用getData都会throw异常。 - Async::Promise<ssize_t> send(const RawBuffer& buffer, int flags = 0);
Async::Promise<ssize_t> Peer::send(const RawBuffer& buffer, int flags)
{
return transport()->asyncWrite(fd_, buffer, flags);
}
使用transport,实现了异步的向client-fd中写入数据,应该是用于response的,但是代码中并没有调用此接口,send的代码就是简单的调用而已。
网友评论