我需要设置一个应用程序来监听多个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中不可用。
那么,如果您事先不知道需要多少听众,那么如何设置多个听众呢?
答案 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();
}
通过这种方式,我们现在拥有了许多线程,您无需在代码中定义多少个。
现在,当我将每个监听器的域放在浏览器中时,我们会得到每个监听器的回复。