2021-05-01 17:42:25 +02:00
|
|
|
#include "mqtt_server.h"
|
|
|
|
|
|
|
|
void MQTTServer::initialize() {
|
|
|
|
evloop = event_base_new();
|
|
|
|
|
|
|
|
if (!evloop) {
|
|
|
|
printf("Could not initialize libevent\n");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::memset(&sin, 0, sizeof(sin));
|
|
|
|
sin.sin_family = AF_INET;
|
|
|
|
evutil_inet_pton(sin.sin_family, bind_address.c_str(), &sin.sin_addr);
|
|
|
|
sin.sin_port = htons(port);
|
|
|
|
|
|
|
|
listener = evconnlistener_new_bind(evloop, MQTTServer::listener_cb,
|
2021-05-01 17:50:58 +02:00
|
|
|
(void *)this,
|
|
|
|
LEV_OPT_REUSEABLE | LEV_OPT_CLOSE_ON_FREE, -1,
|
|
|
|
(struct sockaddr *)&sin, sizeof(sin));
|
2021-05-01 17:42:25 +02:00
|
|
|
|
|
|
|
if (!listener) {
|
|
|
|
std::cerr << "Could not create listener!\n";
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void MQTTServer::listener_cb(struct evconnlistener *listener, evutil_socket_t fd, struct sockaddr *sa, int socklen, void *user_data) {
|
|
|
|
|
|
|
|
MQTTServer *server = static_cast<MQTTServer *>(user_data);
|
|
|
|
|
|
|
|
struct bufferevent *bev;
|
|
|
|
|
|
|
|
bev = bufferevent_socket_new(server->evloop, fd, BEV_OPT_CLOSE_ON_FREE);
|
|
|
|
if (!bev) {
|
|
|
|
std::cerr << "Error constructing bufferevent!\n";
|
|
|
|
event_base_loopbreak(server->evloop);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
server->session_manager->accept_connection(bev);
|
|
|
|
}
|
|
|
|
|
2021-05-01 17:50:58 +02:00
|
|
|
void MQTTServer::run_async() {
|
|
|
|
if (_thread) {
|
|
|
|
printf("MQTTServer::run_async Error! A thread is already runnig!\n");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
_thread = new std::thread([this]() { event_base_dispatch(this->evloop); });
|
2021-05-01 17:42:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
MQTTServer::MQTTServer() {
|
|
|
|
bind_address = "0";
|
|
|
|
port = 1883;
|
2021-05-01 17:50:58 +02:00
|
|
|
_thread = nullptr;
|
2021-05-01 17:42:25 +02:00
|
|
|
|
2021-05-01 17:50:58 +02:00
|
|
|
session_manager = new SessionManager();
|
2021-05-01 17:42:25 +02:00
|
|
|
|
|
|
|
evloop = nullptr;
|
|
|
|
listener = nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
MQTTServer::~MQTTServer() {
|
2021-05-01 17:50:58 +02:00
|
|
|
//this first, as evloop runs in _thread
|
|
|
|
if (evloop && event_base_loopexit(evloop, NULL)) {
|
|
|
|
std::cout << "failed to exit event loop\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
if (_thread) {
|
|
|
|
_thread->join();
|
|
|
|
delete _thread;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (listener)
|
|
|
|
evconnlistener_free(listener);
|
2021-05-01 17:42:25 +02:00
|
|
|
|
2021-05-01 17:50:58 +02:00
|
|
|
if (evloop)
|
|
|
|
event_base_free(evloop);
|
2021-05-01 17:42:25 +02:00
|
|
|
|
2021-05-01 17:50:58 +02:00
|
|
|
delete session_manager;
|
2021-05-01 17:42:25 +02:00
|
|
|
}
|