Question

Je cherche la meilleure façon de modifier le Boost Asio HTTP Server 3 exemple pour maintenir une liste des clients connectés.

Si je modifie server.hpp de l'exemple que:

class server : private boost::noncopyable
{
public:
    typedef std::vector< connection_ptr > ConnectionList;

    // ...

    ConnectionList::const_iterator GetClientList() const
    {
        return connection_list_.begin();
    };

    void handle_accept(const boost::system::error_code& e)
    {
        if (!e)
        {
            connection_list_.push_back( new_connection_ );
            new_connection_->start();
            // ...
        }
    }

private:
    ConnectionList connection_list_;
};

Alors je gâcher la vie de l'objet de connexion de telle sorte qu'il ne va pas hors de portée et vous déconnecter du client, car il a encore une référence maintenue dans le ConnectionList.

Si au contraire mon ConnectionList est défini comme typedef std::vector< boost::weak_ptr< connection > > ConnectionList; alors je risque du client et de débrancher son pointeur détruire pendant que quelqu'un l'utilise de GetClientList().

Quelqu'un a une suggestion sur un bon et moyen sûr de le faire?

Merci, PaulH

Était-ce utile?

La solution

HTTP est sans état. Cela signifie qu'il est difficile de définir ce que « même client actuellement connecté » signifie, sans parler de garder une trace des clients sont à un moment donné. Le seul moment où il y a vraiment un « client » est une mesure du temps une demande est reçue au moment où cette demande est desservie (souvent seulement quelques millisecondes). Une connexion est pas maintenue même pendant toute la durée de téléchargement d'une page -. Au contraire, chaque élément de la page est demandée et envoyée séparément

La méthode typique pour la manipulation est d'utiliser un délai d'attente assez simple - un client est considéré comme « branché » pour une durée arbitraire (quelques minutes) après l'envoi de leur demande. Un cookie quelconque est utilisé pour identifier le client dans l'envoi d'une demande particulière.

Le reste de ce que vous parlez est juste une question de faire en sorte la collection que vous utilisez pour contenir des informations de connexion est thread-safe. Vous avez un thread qui ajoute des connexions, un fil qui les supprime, et N fils qui utilisent les données actuellement dans la liste. Les collections standards ne garantissent pas la sécurité des threads, mais il y a d'autres débrouillez.

Autres conseils

Désolé, je n'ai pas assez la réputation de commentaires, donc je vais écrire ici.

Commentaire sur la réponse: "HTTP est apatride" - mais la connexion est statefull! S'il vous plaît lire attentivement HTTP / 1.1 docs, le comportement par défaut est « Connection: keep-alive », donc si vous implémentez serveur HTTP vous devez attendre une autre requête sur la même connexion. Ceci est particulièrement important pour HTTPS, permet d'économiser beaucoup de temps en réduisant nombre de poignées de main. Voilà pourquoi chaque serveur conforme doit comprendre comment garder les connexions.

En ce qui concerne la question, il y a une certaine logique en vous classe « connexion » - (. Erreur, tout fait, etc) dans chaque gestionnaire d'opération asynchrone, soit vous démarrez une autre opération asynchrone ou d'arrêter la chaîne

Ecrire une fonction dans votre classe « connexion », comme tell_server_im_done, dans cette fonction dites à votre instance « serveur » pour vous retirer de la liste. Vous devez vous donner constructeur « de connexion » un pointeur ou une référence à votre objet serveur pour que cela fonctionne.

conseils multithreading: commencez par faire tout dans le seul fil. Vous avez besoin d'une bonne compréhension du filetage à faire la chose à droite avec plusieurs threads, donc si votre serveur ne soit pas surchargé, gardez-le monothread aussi longtemps que possible. :)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top