【问题标题】:Setting up multiple listeners with c++ casablanca使用 c++ casablanca 设置多个侦听器
【发布时间】:2015-04-06 05:47:43
【问题描述】:

我需要设置一个应用程序来侦听多个 Url,但不知道我什么时候开始有多少 - 这最终会从数据库中读取,但目前它们在演示中是硬编码的。

// MultipleListenerTest.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <string>
#include <vector>

#include <cpprest\http_listener.h>
#include <cpprest\http_client.h>

#include "TestListener.h"               // listener object

using namespace web::http::client;
using namespace web::http::experimental::listener;
using namespace web::http;
using namespace web;

void SetListenerArray();

typedef std::vector<http_listener> httpListeners;

listenerCollection listeners;

TestListener listener1;
TestListener Listener2;
TestListener Listener3;

httpListeners httpListenersList;
void handle_get(http_request request);
void handle_post(http_request request);
void handle_put(http_request request);
void handle_del(http_request request);


int _tmain(int argc, _TCHAR* argv[])
{

    SetListenerArray();

    for each (TestListener tl  in listeners)
    {
        http_listener l(tl.GetUrl());

        l.support(methods::GET, handle_get);
        l.support(methods::POST, handle_post);
        l.support(methods::PUT, handle_put);
        l.support(methods::DEL, handle_del);

        l.open().wait();
        httpListenersList.push_back(l);
    }

    std::string line;
    std::cout << "Press enter to exit" << std::endl;
    std::getline(std::cin, line);

    //listenerVoices_1.close().wait();
    //listenerVoices_2.close().wait();

    return 0;
}

void SetListenerArray()
{

    // first listener
    listener1.SetListenerName(to_string_t("FirstListener"));
    listener1.SetUrl(to_string_t("http://localhost:8010"));
    listeners.push_back(listener1);

    // second listener
    Listener2.SetListenerName(to_string_t("Second Listener"));
    Listener2.SetUrl(to_string_t("http://localhost:8020"));
    listeners.push_back(Listener2);

    //third listener
    Listener3.SetListenerName(to_string_t("Third Listener"));
    Listener3.SetUrl(to_string_t("http://localhost:8030"));
    listeners.push_back(Listener3);

}

void handle_get(http_request request)
{
    for each (TestListener tl  in listeners)
    {
        std::cout << to_utf8string(tl.GetListenerName());
    }
}

void handle_post(http_request request)
{

}

void handle_put(http_request request)
{

}

void handle_del(http_request request)
{

}

用上面的代码行

httpListenersList.push_back(l);

编译失败

错误 1 ​​错误 C2248: 'web::http::experimental::listener::http_listener::http_listener' : 无法访问在类 'web::http::experimental::listener::http_listener' 中声明的私有成员 c :\program files (x86)\microsoft visual studio 12.0\vc\include\xmemory0 593 1 MultipleListenerTest

如果我忽略它,那么实际上没有一个听众在听,你会得到这个网页至少在 Chrome 中不可用。

那么,当您事先不知道需要多少个侦听器时,如何设置多个侦听器呢?

【问题讨论】:

    标签: c++ casablanca


    【解决方案1】:

    使用线程 - 每个线程执行一个侦听器。

    以下是执行监听器的类中的方法。

    void Listener::Start()
    {
        Logger logger;
        std::string logMessage("Starting '" + to_utf8string(GetName()) + "' Listener");
        http_listener httpListener(GetUri());
        std::string listenerName(to_utf8string(name));
    
        logger.log(logMessage);
    
        // listener recieves a GET request.
        httpListener.support(methods::GET, [listenerName](http_request request)
        {
            Logger logger;
    
            std::string logMessage("GET request recieved from " + listenerName);
    
            logger.log(logMessage);
    
            // dummy line just till routing is dealt with
            request.reply(status_codes::OK, logMessage);
    
        });
    
        // open listener and route request 
        httpListener
            .open()
            .then([&httpListener,listenerName](){ 
                Logger logger;
                std::string logMessage(listenerName + " started");
    
                logger.log(logMessage);
    
            }).wait();
    
        // JUST WAIT - we do not want the application to stop
        while (true);
    
    }
    

    然后在程序中执行以下代码,将所有侦听器收集在一个向量中。

    然后扫描向量以创建每个线程。

    RouteMaps rm;
    Logger logger;
    Listeners ls;
    std::vector<std::thread> listener_threads;
    std::vector<Listener> lvector;
    
    std::cout.sync_with_stdio(true);
    
    // collect all the listeners into a vector
    
    for (auto& m : rm.Select()) {
        for (auto& l : ls.Select(m.GetId())) {
            std::string logMessage("Retrieved Listener " + to_utf8string(l.GetName()));
            logger.log(logMessage);
            lvector.push_back(l);
        }
    }
    
    std::cout << "Starting listeners" << std::endl;
    // now create threads for each listener
    for (auto& lstnr : lvector)
    {
        listener_threads.push_back(std::thread{ &Listener::Start, &lstnr });
    }
    

    然而,应用程序将通过并结束 - 停止每个线程。现在在每个线程的底部都有一个永久循环 - 这意味着实际上没有线程会结束。

    要停止程序执行杀死每个线程,它们需要通过以下循环加入主线程。

    for (auto& t : listener_threads)
    {
        t.join();
    }
    

    通过这种方式,我们现在有多个线程,您不必在代码中定义有多少。

    现在,当我将每个侦听器的域放在浏览器中时,我们会收到每个侦听器的回复。

    【讨论】:

      猜你喜欢
      • 2016-11-07
      • 2011-08-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多