使用c ++ casablanca设置多个侦听器

时间:2015-03-15 15:15:48

标签: c++ casablanca

我需要设置一个应用程序来监听多个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中不可用。

那么,如果您事先不知道需要多少听众,那么如何设置多个听众呢?

1 个答案:

答案 0 :(得分: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();
}

通过这种方式,我们现在拥有了许多线程,您无需在代码中定义多少个。

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