diff options
author | Aaron Seigo <aseigo@kde.org> | 2014-12-01 11:54:37 +0100 |
---|---|---|
committer | Aaron Seigo <aseigo@kde.org> | 2014-12-01 12:01:13 +0100 |
commit | 2f52bd2ed26cc151fa90ed9e06b1ea9990f9fc7c (patch) | |
tree | e125101f32ad78a679c63f9c08571d3b11cd691f /resource/listener.cpp | |
parent | af38dcdf3a836a1b94064a617acac387a2de6539 (diff) | |
download | sink-2f52bd2ed26cc151fa90ed9e06b1ea9990f9fc7c.tar.gz sink-2f52bd2ed26cc151fa90ed9e06b1ea9990f9fc7c.zip |
send revision updates from resource to client
this includes an initial revision message on connect
Diffstat (limited to 'resource/listener.cpp')
-rw-r--r-- | resource/listener.cpp | 72 |
1 files changed, 63 insertions, 9 deletions
diff --git a/resource/listener.cpp b/resource/listener.cpp index 8a571e9..5dd8cc3 100644 --- a/resource/listener.cpp +++ b/resource/listener.cpp | |||
@@ -3,13 +3,15 @@ | |||
3 | #include "common/console.h" | 3 | #include "common/console.h" |
4 | #include "common/commands.h" | 4 | #include "common/commands.h" |
5 | #include "common/handshake_generated.h" | 5 | #include "common/handshake_generated.h" |
6 | #include "common/revisionupdate_generated.h" | ||
6 | 7 | ||
7 | #include <QLocalSocket> | 8 | #include <QLocalSocket> |
8 | #include <QTimer> | 9 | #include <QTimer> |
9 | 10 | ||
10 | Listener::Listener(const QString &resource, QObject *parent) | 11 | Listener::Listener(const QString &resource, QObject *parent) |
11 | : QObject(parent), | 12 | : QObject(parent), |
12 | m_server(new QLocalServer(this)) | 13 | m_server(new QLocalServer(this)), |
14 | m_revision(0) | ||
13 | { | 15 | { |
14 | connect(m_server, &QLocalServer::newConnection, | 16 | connect(m_server, &QLocalServer::newConnection, |
15 | this, &Listener::acceptConnection); | 17 | this, &Listener::acceptConnection); |
@@ -34,6 +36,19 @@ Listener::~Listener() | |||
34 | { | 36 | { |
35 | } | 37 | } |
36 | 38 | ||
39 | void Listener::setRevision(unsigned long long revision) | ||
40 | { | ||
41 | if (m_revision != revision) { | ||
42 | m_revision = revision; | ||
43 | updateClientsWithRevision(); | ||
44 | } | ||
45 | } | ||
46 | |||
47 | unsigned long long Listener::revision() const | ||
48 | { | ||
49 | return m_revision; | ||
50 | } | ||
51 | |||
37 | void Listener::closeAllConnections() | 52 | void Listener::closeAllConnections() |
38 | { | 53 | { |
39 | //TODO: close all client connectionsin m_connections | 54 | //TODO: close all client connectionsin m_connections |
@@ -73,7 +88,7 @@ void Listener::clientDropped() | |||
73 | } | 88 | } |
74 | 89 | ||
75 | Console::main()->log("Dropping connection..."); | 90 | Console::main()->log("Dropping connection..."); |
76 | QMutableListIterator<Client> it(m_connections); | 91 | QMutableVectorIterator<Client> it(m_connections); |
77 | while (it.hasNext()) { | 92 | while (it.hasNext()) { |
78 | const Client &client = it.next(); | 93 | const Client &client = it.next(); |
79 | if (client.socket == socket) { | 94 | if (client.socket == socket) { |
@@ -102,24 +117,25 @@ void Listener::readFromSocket() | |||
102 | } | 117 | } |
103 | 118 | ||
104 | Console::main()->log("Reading from socket..."); | 119 | Console::main()->log("Reading from socket..."); |
105 | QMutableListIterator<Client> it(m_connections); | 120 | for (Client &client: m_connections) { |
106 | while (it.hasNext()) { | ||
107 | Client &client = it.next(); | ||
108 | if (client.socket == socket) { | 121 | if (client.socket == socket) { |
109 | Console::main()->log(QString(" Client: %1").arg(client.name)); | 122 | Console::main()->log(QString(" Client: %1").arg(client.name)); |
110 | client.commandBuffer += socket->readAll(); | 123 | client.commandBuffer += socket->readAll(); |
111 | processClientBuffer(client); | 124 | // FIXME: schedule these rather than process them all at once |
125 | // right now this can lead to starvation of clients due to | ||
126 | // one overly active client | ||
127 | while (processClientBuffer(client)) {} | ||
112 | break; | 128 | break; |
113 | } | 129 | } |
114 | } | 130 | } |
115 | } | 131 | } |
116 | 132 | ||
117 | void Listener::processClientBuffer(Client &client) | 133 | bool Listener::processClientBuffer(Client &client) |
118 | { | 134 | { |
119 | static const int headerSize = (sizeof(int) * 2); | 135 | static const int headerSize = (sizeof(int) * 2); |
120 | Console::main()->log(QString("processing %1").arg(client.commandBuffer.size())); | 136 | Console::main()->log(QString("processing %1").arg(client.commandBuffer.size())); |
121 | if (client.commandBuffer.size() < headerSize) { | 137 | if (client.commandBuffer.size() < headerSize) { |
122 | return; | 138 | return false; |
123 | } | 139 | } |
124 | 140 | ||
125 | int commandId, size; | 141 | int commandId, size; |
@@ -134,12 +150,50 @@ void Listener::processClientBuffer(Client &client) | |||
134 | case Commands::HandshakeCommand: { | 150 | case Commands::HandshakeCommand: { |
135 | auto buffer = Toynadi::GetHandshake(data.constData()); | 151 | auto buffer = Toynadi::GetHandshake(data.constData()); |
136 | Console::main()->log(QString(" Handshake from %1").arg(buffer->name()->c_str())); | 152 | Console::main()->log(QString(" Handshake from %1").arg(buffer->name()->c_str())); |
137 | //TODO: reply? | 153 | sendCurrentRevision(client); |
138 | break; | 154 | break; |
139 | } | 155 | } |
140 | default: | 156 | default: |
141 | // client.hasSentCommand = true; | 157 | // client.hasSentCommand = true; |
142 | break; | 158 | break; |
143 | } | 159 | } |
160 | |||
161 | return client.commandBuffer.size() >= headerSize; | ||
162 | } else { | ||
163 | return false; | ||
164 | } | ||
165 | } | ||
166 | |||
167 | void Listener::sendCurrentRevision(Client &client) | ||
168 | { | ||
169 | if (!client.socket || !client.socket->isValid()) { | ||
170 | return; | ||
171 | } | ||
172 | |||
173 | flatbuffers::FlatBufferBuilder fbb; | ||
174 | auto command = Toynadi::CreateRevisionUpdate(fbb, m_revision); | ||
175 | Toynadi::FinishRevisionUpdateBuffer(fbb, command); | ||
176 | const int commandId = Commands::RevisionUpdateCommand; | ||
177 | const int dataSize = fbb.GetSize(); | ||
178 | client.socket->write((const char*)&commandId, sizeof(int)); | ||
179 | client.socket->write((const char*)&dataSize, sizeof(int)); | ||
180 | client.socket->write((const char*)fbb.GetBufferPointer(), dataSize); | ||
181 | } | ||
182 | |||
183 | void Listener::updateClientsWithRevision() | ||
184 | { | ||
185 | flatbuffers::FlatBufferBuilder fbb; | ||
186 | auto command = Toynadi::CreateRevisionUpdate(fbb, m_revision); | ||
187 | Toynadi::FinishRevisionUpdateBuffer(fbb, command); | ||
188 | const int commandId = Commands::RevisionUpdateCommand; | ||
189 | const int dataSize = fbb.GetSize(); | ||
190 | |||
191 | for (const Client &client: m_connections) { | ||
192 | if (!client.socket || !client.socket->isValid()) { | ||
193 | continue; | ||
194 | } | ||
195 | client.socket->write((const char*)&commandId, sizeof(int)); | ||
196 | client.socket->write((const char*)&dataSize, sizeof(int)); | ||
197 | client.socket->write((const char*)fbb.GetBufferPointer(), dataSize); | ||
144 | } | 198 | } |
145 | } | 199 | } |