Je voulais écrire un wrapper sur le boost ASIO pour une implémentation tcp client/serveur. L'interface de boost ASIO est vraiment sympa, mais la raison d'avoir wrapper est de pouvoir remplacer la boucle d'événement par autre chose. Dans notre cas, nous avons juste besoin d'invoquer la même fonction de gestionnaire pour chaque lecture asynchrone, l'application n'a pas besoin de passer le gestionnaire pour chaque appel asyncRead. Il est donc utile d'enregistrer le gestionnaire pour une fois. Une manière que j'ai essayée est comme ceci -Boost ASIO avec CRTP ou PBCP ou Duck-type
template <class Connection>
struct TCPClient { // implements the interface with ASIO
Connection *_connection;
void setConnection (Connection *connection)
{
_connection = connection;
}
void asyncRead()
{
_socket.async_read_some(boost::asio::null_buffers(),
[this] (ErrorType err, unsigned a) {
if (_connection) _connection->handleRead(err);
if (!err) asyncRead();
});
}
};
que je pouvais faire la même avec CRTP
class MyConnection : public TCPClient<MyConnection> {
void readHandler (TCPClient::ErrType err)
{
}
};
Et en classe TCPClient la AsyncRead sera
void asyncRead()
{
_socket.async_read_some(boost::asio::null_buffers(),
[this] (ErrorType err, unsigned a) {
((Connection *)this)->handleRead(err);
if (!err) asyncRead();
});
}
Ce dans le cas est utile que la durée de vie de la TCPClient et la connexion est le même.
Ou PBCP
template <typename Connection>
class TCPClient : public Connection {
void asyncRead()
{
_socket.async_read_some(boost::asio::null_buffers(),
[this] (ErrorType err, unsigned a) {
Connection::handleRead(err);
if (!err) asyncRead();
});
}
};
Je ne pense pas vraiment il y a une IS-A par rapport b/w tcpclient et connexion. Je suis confus si l'un de ces schémas est bon. (Aussi je me demande pourquoi ASIO n'a pas de schéma où il met en cache le gestionnaire une fois et l'appelle à chaque fois.) En cas de lecture asynchrone, normalement il n'y a pas de contexte à renvoyer. Boost ASIO copier le gestionnaire de lecture à chaque fois + allocation de mémoire pour stocker est vraiment mauvais.Ainsi, en fonction des résultats de test, nous pouvons avoir à changer la boucle d'événement à quelque chose de personnalisé)
Asio fournit des crochets pour contrôler la mémoire du gestionnaire allocation (voir [Custom Memory Allocation] (http://www.boost.org/doc/libs/1_63_0/doc/html/boost_asio.html#boost_asio.overview.core.allocation]). Asio est conçu pour servir de base à d'autres abstractions, et le paradigme _one-callback-per-operation_ facilite la mise en œuvre d'autres paradigmes. Avant d'écrire une boucle d'événement personnalisée, je vous encourage fortement à considérer [libuv] (https://github.com/libuv/libuv), qui prend en charge le fait que le même rappel soit appelé chaque fois que des données sont disponibles. –
Je n'ai jamais entendu parler de PBCP. Qu'Est-ce que c'est? Google, assurément, n'en sait rien. (Si je devais faire une extension d'acronyme du code, je devinerais "Parameterized Base Class Pattern"? Nous appellerions cela Mixin) – sehe
@sehe. Oui c'est ça. – MGH