Commit 2a3138f9c422ddeea1055d4773e84cf437b687b7
1 parent
fec1aa82
Reorder stuff for storing subscription store
Showing
11 changed files
with
105 additions
and
32 deletions
CMakeLists.txt
client.cpp
| ... | ... | @@ -115,7 +115,7 @@ std::string Client::repr() |
| 115 | 115 | return a.str(); |
| 116 | 116 | } |
| 117 | 117 | |
| 118 | -bool Client::bufferToMqttPackets(std::vector<MqttPacket> &packetQueueIn) | |
| 118 | +bool Client::bufferToMqttPackets(std::vector<MqttPacket> &packetQueueIn, Client_p &sender) | |
| 119 | 119 | { |
| 120 | 120 | while (getReadBufBytesUsed() >= MQTT_HEADER_LENGH) |
| 121 | 121 | { |
| ... | ... | @@ -144,7 +144,7 @@ bool Client::bufferToMqttPackets(std::vector<MqttPacket> &packetQueueIn) |
| 144 | 144 | |
| 145 | 145 | if (packet_length <= getReadBufBytesUsed()) |
| 146 | 146 | { |
| 147 | - MqttPacket packet(&readbuf[ri], packet_length, remaining_length_i, this); | |
| 147 | + MqttPacket packet(&readbuf[ri], packet_length, remaining_length_i, sender); | |
| 148 | 148 | packetQueueIn.push_back(std::move(packet)); |
| 149 | 149 | |
| 150 | 150 | ri += packet_length; | ... | ... |
client.h
| ... | ... | @@ -5,6 +5,8 @@ |
| 5 | 5 | #include <unistd.h> |
| 6 | 6 | #include <vector> |
| 7 | 7 | |
| 8 | +#include "forward_declarations.h" | |
| 9 | + | |
| 8 | 10 | #include "threaddata.h" |
| 9 | 11 | #include "mqttpacket.h" |
| 10 | 12 | #include "exceptions.h" |
| ... | ... | @@ -12,11 +14,6 @@ |
| 12 | 14 | #define CLIENT_BUFFER_SIZE 1024 |
| 13 | 15 | #define MQTT_HEADER_LENGH 2 |
| 14 | 16 | |
| 15 | -class ThreadData; | |
| 16 | -typedef std::shared_ptr<ThreadData> ThreadData_p; | |
| 17 | - | |
| 18 | -class MqttPacket; | |
| 19 | - | |
| 20 | 17 | class Client |
| 21 | 18 | { |
| 22 | 19 | int fd; |
| ... | ... | @@ -90,7 +87,7 @@ public: |
| 90 | 87 | |
| 91 | 88 | int getFd() { return fd;} |
| 92 | 89 | bool readFdIntoBuffer(); |
| 93 | - bool bufferToMqttPackets(std::vector<MqttPacket> &packetQueueIn); | |
| 90 | + bool bufferToMqttPackets(std::vector<MqttPacket> &packetQueueIn, Client_p &sender); | |
| 94 | 91 | void setClientProperties(const std::string &clientId, const std::string username, bool connectPacketSeen, uint16_t keepalive); |
| 95 | 92 | void setAuthenticated(bool value) { authenticated = value;} |
| 96 | 93 | bool getAuthenticated() { return authenticated; } |
| ... | ... | @@ -104,6 +101,4 @@ public: |
| 104 | 101 | |
| 105 | 102 | }; |
| 106 | 103 | |
| 107 | -typedef std::shared_ptr<Client> Client_p; | |
| 108 | - | |
| 109 | 104 | #endif // CLIENT_H | ... | ... |
forward_declarations.h
0 โ 100644
| 1 | +#ifndef FORWARD_DECLARATIONS_H | |
| 2 | +#define FORWARD_DECLARATIONS_H | |
| 3 | + | |
| 4 | +#include <memory> | |
| 5 | + | |
| 6 | +class Client; | |
| 7 | +typedef std::shared_ptr<Client> Client_p; | |
| 8 | +class ThreadData; | |
| 9 | +typedef std::shared_ptr<ThreadData> ThreadData_p; | |
| 10 | +class MqttPacket; | |
| 11 | +class SubscriptionStore; | |
| 12 | + | |
| 13 | + | |
| 14 | +#endif // FORWARD_DECLARATIONS_H | ... | ... |
main.cpp
| ... | ... | @@ -7,10 +7,12 @@ |
| 7 | 7 | #include <thread> |
| 8 | 8 | #include <vector> |
| 9 | 9 | |
| 10 | + | |
| 10 | 11 | #include "utils.h" |
| 11 | 12 | #include "threaddata.h" |
| 12 | 13 | #include "client.h" |
| 13 | 14 | #include "mqttpacket.h" |
| 15 | +#include "subscriptionstore.h" | |
| 14 | 16 | |
| 15 | 17 | #define MAX_EVENTS 1024 |
| 16 | 18 | #define NR_OF_THREADS 4 |
| ... | ... | @@ -50,7 +52,7 @@ void do_thread_work(ThreadData *threadData) |
| 50 | 52 | } |
| 51 | 53 | else |
| 52 | 54 | { |
| 53 | - client->bufferToMqttPackets(packetQueueIn); // TODO: different, because now I need to give the packet a raw pointer. | |
| 55 | + client->bufferToMqttPackets(packetQueueIn, client); | |
| 54 | 56 | } |
| 55 | 57 | } |
| 56 | 58 | if (cur_ev.events & EPOLLOUT) |
| ... | ... | @@ -64,7 +66,7 @@ void do_thread_work(ThreadData *threadData) |
| 64 | 66 | |
| 65 | 67 | for (MqttPacket &packet : packetQueueIn) |
| 66 | 68 | { |
| 67 | - packet.handle(); | |
| 69 | + packet.handle(threadData->getSubscriptionStore()); | |
| 68 | 70 | } |
| 69 | 71 | packetQueueIn.clear(); |
| 70 | 72 | } |
| ... | ... | @@ -100,11 +102,13 @@ int main() |
| 100 | 102 | ev.events = EPOLLIN; |
| 101 | 103 | check<std::runtime_error>(epoll_ctl(epoll_fd_accept, EPOLL_CTL_ADD, listen_fd, &ev)); |
| 102 | 104 | |
| 105 | + std::shared_ptr<SubscriptionStore> subscriptionStore(new SubscriptionStore()); | |
| 106 | + | |
| 103 | 107 | std::vector<std::shared_ptr<ThreadData>> threads; |
| 104 | 108 | |
| 105 | 109 | for (int i = 0; i < NR_OF_THREADS; i++) |
| 106 | 110 | { |
| 107 | - std::shared_ptr<ThreadData> t(new ThreadData(i)); | |
| 111 | + std::shared_ptr<ThreadData> t(new ThreadData(i, subscriptionStore)); | |
| 108 | 112 | std::thread thread(do_thread_work, t.get()); |
| 109 | 113 | t->thread = std::move(thread); |
| 110 | 114 | threads.push_back(t); | ... | ... |
mqttpacket.cpp
| ... | ... | @@ -3,7 +3,7 @@ |
| 3 | 3 | #include <iostream> |
| 4 | 4 | #include <list> |
| 5 | 5 | |
| 6 | -MqttPacket::MqttPacket(char *buf, size_t len, size_t fixed_header_length, Client *sender) : | |
| 6 | +MqttPacket::MqttPacket(char *buf, size_t len, size_t fixed_header_length, Client_p &sender) : | |
| 7 | 7 | bites(len), |
| 8 | 8 | fixed_header_length(fixed_header_length), |
| 9 | 9 | sender(sender) |
| ... | ... | @@ -46,14 +46,14 @@ MqttPacket::MqttPacket(const SubAck &subAck) : |
| 46 | 46 | bites[1] = returnList.size() + 1; // TODO: make some generic way of calculating the header and use the multi-byte length |
| 47 | 47 | } |
| 48 | 48 | |
| 49 | -void MqttPacket::handle() | |
| 49 | +void MqttPacket::handle(std::shared_ptr<SubscriptionStore> &subscriptionStore) | |
| 50 | 50 | { |
| 51 | 51 | if (packetType == PacketType::CONNECT) |
| 52 | 52 | handleConnect(); |
| 53 | 53 | else if (packetType == PacketType::PINGREQ) |
| 54 | 54 | sender->writePingResp(); |
| 55 | 55 | else if (packetType == PacketType::SUBSCRIBE) |
| 56 | - handleSubscribe(); | |
| 56 | + handleSubscribe(subscriptionStore); | |
| 57 | 57 | } |
| 58 | 58 | |
| 59 | 59 | void MqttPacket::handleConnect() |
| ... | ... | @@ -137,7 +137,7 @@ void MqttPacket::handleConnect() |
| 137 | 137 | } |
| 138 | 138 | } |
| 139 | 139 | |
| 140 | -void MqttPacket::handleSubscribe() | |
| 140 | +void MqttPacket::handleSubscribe(std::shared_ptr<SubscriptionStore> &subscriptionStore) | |
| 141 | 141 | { |
| 142 | 142 | uint16_t packet_id = readTwoBytesToUInt16(); |
| 143 | 143 | |
| ... | ... | @@ -147,6 +147,7 @@ void MqttPacket::handleSubscribe() |
| 147 | 147 | uint16_t topicLength = readTwoBytesToUInt16(); |
| 148 | 148 | std::string topic(readBytes(topicLength), topicLength); |
| 149 | 149 | std::cout << sender->repr() << " Subscribed to " << topic << std::endl; |
| 150 | + subscriptionStore->addSubscription(sender, topic); | |
| 150 | 151 | subs.push_back(std::move(topic)); |
| 151 | 152 | } |
| 152 | 153 | |
| ... | ... | @@ -159,6 +160,16 @@ void MqttPacket::handleSubscribe() |
| 159 | 160 | } |
| 160 | 161 | |
| 161 | 162 | |
| 163 | +Client_p MqttPacket::getSender() const | |
| 164 | +{ | |
| 165 | + return sender; | |
| 166 | +} | |
| 167 | + | |
| 168 | +void MqttPacket::setSender(const Client_p &value) | |
| 169 | +{ | |
| 170 | + sender = value; | |
| 171 | +} | |
| 172 | + | |
| 162 | 173 | char *MqttPacket::readBytes(size_t length) |
| 163 | 174 | { |
| 164 | 175 | if (pos + length > bites.size()) | ... | ... |
mqttpacket.h
| ... | ... | @@ -6,18 +6,19 @@ |
| 6 | 6 | #include <vector> |
| 7 | 7 | #include <exception> |
| 8 | 8 | |
| 9 | +#include "forward_declarations.h" | |
| 10 | + | |
| 9 | 11 | #include "client.h" |
| 10 | 12 | #include "exceptions.h" |
| 11 | 13 | #include "types.h" |
| 12 | - | |
| 13 | -class Client; | |
| 14 | +#include "subscriptionstore.h" | |
| 14 | 15 | |
| 15 | 16 | |
| 16 | 17 | class MqttPacket |
| 17 | 18 | { |
| 18 | 19 | std::vector<char> bites; |
| 19 | 20 | size_t fixed_header_length = 0; |
| 20 | - Client *sender; | |
| 21 | + Client_p sender; | |
| 21 | 22 | size_t pos = 0; |
| 22 | 23 | ProtocolVersion protocolVersion = ProtocolVersion::None; |
| 23 | 24 | |
| ... | ... | @@ -29,18 +30,20 @@ class MqttPacket |
| 29 | 30 | |
| 30 | 31 | public: |
| 31 | 32 | PacketType packetType = PacketType::Reserved; |
| 32 | - MqttPacket(char *buf, size_t len, size_t fixed_header_length, Client *sender); | |
| 33 | + MqttPacket(char *buf, size_t len, size_t fixed_header_length, Client_p &sender); | |
| 33 | 34 | MqttPacket(const ConnAck &connAck); |
| 34 | 35 | MqttPacket(const SubAck &subAck); |
| 35 | 36 | |
| 36 | - void handle(); | |
| 37 | + void handle(std::shared_ptr<SubscriptionStore> &subscriptionStore); | |
| 37 | 38 | void handleConnect(); |
| 38 | - void handleSubscribe(); | |
| 39 | + void handleSubscribe(std::shared_ptr<SubscriptionStore> &subscriptionStore); | |
| 39 | 40 | void handlePing(); |
| 40 | 41 | |
| 41 | 42 | size_t getSize() { return bites.size(); } |
| 42 | 43 | const std::vector<char> &getBites() { return bites; } |
| 43 | 44 | |
| 45 | + Client_p getSender() const; | |
| 46 | + void setSender(const Client_p &value); | |
| 44 | 47 | }; |
| 45 | 48 | |
| 46 | 49 | #endif // MQTTPACKET_H | ... | ... |
subscriptionstore.cpp
0 โ 100644
subscriptionstore.h
0 โ 100644
| 1 | +#ifndef SUBSCRIPTIONSTORE_H | |
| 2 | +#define SUBSCRIPTIONSTORE_H | |
| 3 | + | |
| 4 | +#include <unordered_map> | |
| 5 | +#include <list> | |
| 6 | + | |
| 7 | +#include "forward_declarations.h" | |
| 8 | + | |
| 9 | +#include "client.h" | |
| 10 | + | |
| 11 | +class SubscriptionStore | |
| 12 | +{ | |
| 13 | + std::unordered_map<std::string, std::list<Client_p>> subscriptions; | |
| 14 | +public: | |
| 15 | + SubscriptionStore(); | |
| 16 | + | |
| 17 | + void addSubscription(Client_p &client, std::string &topic); | |
| 18 | + | |
| 19 | + // work with read copies intead of mutex/lock over the central store | |
| 20 | + void getReadCopy(); // TODO | |
| 21 | +}; | |
| 22 | + | |
| 23 | +#endif // SUBSCRIPTIONSTORE_H | ... | ... |
threaddata.cpp
| 1 | 1 | #include "threaddata.h" |
| 2 | 2 | |
| 3 | 3 | |
| 4 | -ThreadData::ThreadData(int threadnr) : | |
| 4 | +ThreadData::ThreadData(int threadnr, std::shared_ptr<SubscriptionStore> &subscriptionStore) : | |
| 5 | + subscriptionStore(subscriptionStore), | |
| 5 | 6 | threadnr(threadnr) |
| 6 | 7 | { |
| 7 | 8 | epollfd = check<std::runtime_error>(epoll_create(999)); |
| ... | ... | @@ -29,3 +30,8 @@ void ThreadData::removeClient(Client_p client) |
| 29 | 30 | { |
| 30 | 31 | clients_by_fd.erase(client->getFd()); |
| 31 | 32 | } |
| 33 | + | |
| 34 | +std::shared_ptr<SubscriptionStore> &ThreadData::getSubscriptionStore() | |
| 35 | +{ | |
| 36 | + return subscriptionStore; | |
| 37 | +} | ... | ... |
threaddata.h
| ... | ... | @@ -2,18 +2,23 @@ |
| 2 | 2 | #define THREADDATA_H |
| 3 | 3 | |
| 4 | 4 | #include <thread> |
| 5 | -#include "utils.h" | |
| 5 | + | |
| 6 | 6 | #include <sys/epoll.h> |
| 7 | 7 | #include <sys/eventfd.h> |
| 8 | -#include "client.h" | |
| 9 | 8 | #include <map> |
| 10 | 9 | |
| 11 | -class Client; | |
| 12 | -typedef std::shared_ptr<Client> Client_p; | |
| 10 | +#include "forward_declarations.h" | |
| 11 | + | |
| 12 | +#include "client.h" | |
| 13 | +#include "subscriptionstore.h" | |
| 14 | +#include "utils.h" | |
| 15 | + | |
| 16 | + | |
| 13 | 17 | |
| 14 | 18 | class ThreadData |
| 15 | 19 | { |
| 16 | 20 | std::map<int, Client_p> clients_by_fd; |
| 21 | + std::shared_ptr<SubscriptionStore> subscriptionStore; | |
| 17 | 22 | |
| 18 | 23 | public: |
| 19 | 24 | std::thread thread; |
| ... | ... | @@ -21,13 +26,12 @@ public: |
| 21 | 26 | int epollfd = 0; |
| 22 | 27 | int event_fd = 0; |
| 23 | 28 | |
| 24 | - ThreadData(int threadnr); | |
| 29 | + ThreadData(int threadnr, std::shared_ptr<SubscriptionStore> &subscriptionStore); | |
| 25 | 30 | |
| 26 | 31 | void giveClient(Client_p client); |
| 27 | 32 | Client_p getClient(int fd); |
| 28 | 33 | void removeClient(Client_p client); |
| 34 | + std::shared_ptr<SubscriptionStore> &getSubscriptionStore(); | |
| 29 | 35 | }; |
| 30 | 36 | |
| 31 | -typedef std::shared_ptr<ThreadData> ThreadData_p; | |
| 32 | - | |
| 33 | 37 | #endif // THREADDATA_H | ... | ... |