在C++中实现协程
我在整理tars和taf的协程逻辑的时候,也实现了一个纯净版的协程框架以便于理解
网络框架
类图
看下把tcpconnection改成回调中智能指针是否合理
classDiagram
direction TB
class EventLoop {
+void wait()
+void stop()
+void addPoller(uint64_t type, shared_ptr~Poller~ poller)
+weak_ptr<Poller> getPoller(uint64_t pollerType)\n在Connector和Acceptor中用来给TcpConnection创建Event的时候指定Poller
-map<uint64_t, shared_ptr<Poller>> pollers_;
}
class Poller {
<<interface>>
+vector<weak_ptr<Event>> poll(string&)
+void addOrUpdateEvent(shared_ptr<Event> event)
+void removeEvent(Event *event)
}
class Epoller {
+vector<weak_ptr<Event>> poll(string&)
+void addOrUpdateEvent(shared_ptr~Event~ event)
+void removeEvent(Event *event)
}
class Event {
+Event(weak_ptr~Poller~ poller, int64_t fd)
+void setReadEvent(function<void#40;#41;>)
+void setWriteEvent(function<void#40;#41;>)
-weak_ptr~Poller~ poller_;
}
Epoller ..|> Poller
EventLoop ..> Poller
Epoller ..> Event
Event ..> Poller
class Socket {
+void bind(const string &addr, int port) Acceptor使用
+void listen() Acceptor使用
+void accept() Acceptor使用
+void connect(const string &addr, int port) Connector使用
+int read(char* buf, int len) TcpConnection使用
+int write(char* buf, int len) TcpConnection使用
+void setNoblock()
}
class Buffer {
+void push(const char *buf, uint64_t len)
+uint64_t popHead(char *buf, uint64_t len)
-void write(const char *buf, uint64_t len) TcpConnection使用
-uint64_t Read(char *buf, uint64_t len) TcpConnection使用
}
class TcpConnection {
+TcpConnection(unique_ptr~Socket~ &&socket, shared_ptr~Event~ &event)
+void asyncRead(uint64_t expectSize, function<void#40;const string &errMsg#41;> func)
+void asyncReadAny(function<void#40;const string &errMsg#41;>)
+void asyncWrite(function<void#40;const string &errMsg#41;>)
+void finish(const string &errMsg)
-void initAccepted(string &errMsg)
-void initConnected(string &errMsg)
-void setFinishHandler(function<void#40;const string &errMsg,\nshared_ptr<TcpConnection>)>)
-Buffer readBuffer_;
-Buffer writeBuffer_;
-unique_ptr~Socket~ socket_;
-shared_ptr~Event~ event_;
}
class Acceptor {
+Acceptor(EventLoop &loop, const string &addr, int port)
+void listen(string &errMsg)
+void setNewConnectionHandler(function<void#40;int fd#41;>)
-unique_ptr~Socket~ socket_;
-shared_ptr~Event~ event_;
}
class Connector {
Connector(EventLoop &loop, const string &addr, int port)
+void connect(string &errMsg)
+void setNewConnectionHandler(function<void#40;unique_ptr<Socket>&,\nshared_ptr<Event>)>)
+void setConnectFailedHandler(function<void#40;const string &errMsg#41;>)
-unique_ptr~Socket~ socket_;
-shared_ptr~Event~ event_;
}
Socket --* TcpConnection
Buffer --o TcpConnection
Event --o TcpConnection
Socket --* Acceptor
Event --o Acceptor
Socket --* Connector
Event --o Connector
class Server {
+Server(EventLoop &loop, const string &addr, int port)
+void serve(string &errMsg)
+void setConnectedHandler(function<void#40;const string &errMsg,TcpConnection)>)\n连接成功以后,在connected回调的参数来获取连接读取数据
+void setDisconnectedHandler(function<void#40;const string &errMsg#41;>)
-Acceptor acceptor_;
set~shared_ptr~TcpConnection~~ connections_;
}
TcpConnection --o Server
Acceptor --* Server
Client --> EventLoop
class Client {
+Client(EventLoop &loop, const string &addr, int port)
+void asyncConnect(string &errMsg)
+void setConnectedHandler(function<void#40;const string &errMsg#41;>)
+void setDisconnectedHandler(function<void#40;const string &errMsg#41;>)
+TcpConnection& getTcpConnection()\n连接成功以后,在connected回调中调用来获取连接读取数据
-Connector connector_;
-shared_ptr~TcpConnection~ connection_;
}
Connector --* Client
TcpConnection --o Client
Server --> EventLoop
服务端流程图
sequenceDiagram
participant EventLoop
Server ->>+ Server : serve()
Server ->>+ Acceptor : setNewConnectionHandler()<br>listen()
Acceptor ->>- Server : return
Server ->>- Server : return
EventLoop ->>+ EventLoop : wait()
loop while(true)
EventLoop ->>+ EventLoop : runOnce()
EventLoop ->>+ Epoller : auto events = poll()
Epoller ->> Epoller : ::epoll_wait(epollfd_, &(*pollEvents_.begin()), maxSize_)
Epoller ->>- EventLoop : return
loop for event in events
EventLoop ->>+ Event : do()
Event ->>+ EventLoop : return
end
EventLoop ->>- EventLoop : return
end
EventLoop ->>- EventLoop : return
客户端流程图
1 | ``` |