C 设计:多个TCP客户端,Boost ASIO和观察者
C++ Design: Multiple TCP clients, boost asio and observers
在我的系统中,我有一群TCP客户端,我对如何设计它感到有些困惑(我的大部分经验是在C中,因此不安全感(。我正在使用Boost ASIO来管理连接。这些是我拥有的组件
- tcpstream类:Boost Asio 的薄包装器
- IPC协议,该协议通过TCP实施协议:基本上每个消息都以类型和长度字段开头因此我们可以从流中读取各个消息。
- 处理消息的连接类
- 监视连接的观察者类
我正在编写伪C 代码是简洁的。我想你会得到这个想法
class TCPStream {
boost::asio::socket socket_;
public:
template <typename F>
void connect (F f)
{
socket_.connect(f);
}
template <typename F>
void read (F f)
{
socket_.read(f);
}
};
class IpcProtocol : public TCPStream {
public:
template <typename F
void read (F f)
{
TCPStream::read(
[f] (buffer, err) {
while (msg = read_indvidual_message(buffer)) {
// **** this is a violation of how this pattern is
// supposed to work. Ideally there should a callback
// for individual message. Here the same callback
// is called for N no. of messages. But in our case
// its the same callback everytime so this should be
// fine - just avoids some function calls.
f(msg);
};
};
)
}
};
可以说我有一堆TCP连接,还有一个处理程序类对于每个连接。让我们命名IT Connection1,Connection2 ...
class Connection {
virtual int type() = 0;
};
class Connection1 : public Connection {
shared_ptr<IpcProtocol> ipc_;
int type ()
{
return 1;
}
void start ()
{
ipc_.connect([self = shared_from_this()](){ self->connected(); });
ipc_.read(
[self = shared_from_this()](msg, err) {
if (!err)
self->process(msg);
} else {
self->error();
}
});
}
void connected ()
{
observer.notify_connected(shared_from_this());
}
void error ()
{
observer.notify_error(shared_from_this());
}
};
此模式以一种或其他方式重复所有连接。消息由连接类本身处理。但这会让其他事件[连接,错误]与观察者。原因 -
- 重新启动连接,每次断开连接
- 一群人需要知道是否建立了连接,以便他们可以将初始请求/浓汤发送到服务器。
- 有一些需要根据Muliple连接的连接状态完成的事情例如:如果建立Connection1和Connection2,则启动Connection3等。
我在那里添加了一个中间观察者类,以便观察者每次重新启动时都必须直接连接到连接。每次连接中断,连接类都将被删除并创建新的连接类。
class Listeners {
public:
virtual void notify_error(shared_ptr<Connection>) = 0;
virtual void notify_connect(shared_ptr<Connection>) = 0;
virtual void interested(int type) = 0;
};
class Observer {
std::vector<Listeners *> listeners_;
public:
void notify_connect(shared_ptr<Connection> connection)
{
for (listener : listeners_) {
if (listener->interested(connection->type())) {
listener->notify_error(connection);
}
}
}
};
现在,这是对此作品的粗略原型。但是我想知道这个课程是否 任何好处。有多个流媒体服务器将不断产生状态,并将其发送到我的模块以H/W中的状态编程。这需要可扩展,因为将来会添加更多的客户。
线程
旧版代码每个TCP连接具有一个线程,这很好。在这里,我试图在同一线程上处理多个连接。仍然会有多个呼叫ioservice的线程。因此,观察者将在多个线程上运行。我打算每个听众都有一个静音,以免听众同时获得多个事件。
http通过TCP实现协议,因此HTTP服务器ASIO示例是设计的好起点,尤其是:HTTP Server 2
,HTTP Server 3
和HTTP Server 4
。
注意:连接生命周期可能是一个问题,尤其是因为您打算将类成员功能用作处理程序,请参阅此处的问题和答案:如何设计Boost :: Asio套接字或其包装器的正确发布。
相关文章:
- 理解boost::asio-async_read在无需读取内容时的行为
- C++Boost Asio Pool线程,带有lambda函数和传递引用变量
- boost::asio::steady_timer()与sleep()我应该使用哪一个
- boost::asio如何生成多个协同程序,然后加入它们
- 从 Boost ASIO 获取 epoll 描述符 io_service对象
- 如何在 Boost.Asio 中使用 Zero-copy sendmsg/receive
- 如何使用 Boost Asio 在 Android 上获取我的本地 udp IP 地址?
- 执行时使用 boost::asio::d eadline_timer 时出错
- Boost.Asio/OpenSSL HTTPS GET certificate trouble
- boost::asio data owning `ConstBufferSequence`
- 如何替换此示例代码片段中已弃用的handler_type_t或 boost::asio::handler_type?
- 如何将boost::asio::d eadline_timer 与Qt一起使用?
- 将更高的优先级设置为 boost::asio 线程处理进程
- Async_read_until限制读取的字节大小(Boost::asio)
- 程序崩溃使用boost::asio
- boost::asio 无法捕获 SIGINT
- TCP 服务器的异步读取使用 boost::asio 打印客户端套接字发送的数据
- 如何在 boost::asio 中将打包的结构作为消息传递?(无序列化)
- 如何使用C++和Boost Asio从HTTP发布请求中获取键值
- std::boost::asio::p ost / dispatch 使用哪个io_context?