Skip to content

Commit

Permalink
the most recent client could disconnect other clients (#19)
Browse files Browse the repository at this point in the history
  • Loading branch information
mkalkbrenner authored Mar 14, 2024
1 parent 0d0664f commit 5d88284
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 6 deletions.
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ The DmdStreamHeader is defined as a struct:
uint16_t width = 0;
uint16_t height = 0;
uint8_t buffered = 0; // 0 => not buffered, 1 => buffered
uint8_t disconnectOthers = 0; // 0 => no, 1 => yes
uint32_t length = 0;
};

Expand Down Expand Up @@ -121,7 +122,10 @@ grayscale content.
So if you want to write a general purpose client to display images or text, you're adviced to use `Mode::RGB24` or `Mode::RGB216`!
The `buffered` flag set to `1` means that the current data not just gets displayed, but also buffered for later use.
As soon as some buffered data exists, it will be displayed instead of a black screen if a client disconnects.
As soon as some buffered data exists, it will be displayed instead of a black screen if a client disconnects.
The `disconnectOthers` flag set to `1` means that any other client get disconnected except the most recent one.
But only the most recent one is allowed to set this flag.
### Notes
Expand All @@ -139,6 +143,8 @@ To send a RGB24 image of 4x2 pixels, you have to sent these two packages, a head
0x02 0x00 0x00 0x00 // Mode::RGB24 (if your system is big endian, the byte order needs to be swapped)
0x04 0x00 // width 4 (if your system is big endian, the byte order needs to be swapped)
0x02 0x00 // height 2 (if your system is big endian, the byte order needs to be swapped)
0x00 // not buffered
0x00 // don't disconnect others
0x18 0x00 0x00 0x00 // payload length 24 (if your system is big endian, the byte order needs to be swapped)
```
Expand Down
1 change: 1 addition & 0 deletions include/DMDUtil/DMD.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ class DMDUTILAPI DMD
uint16_t width = 0;
uint16_t height = 0;
uint8_t buffered = 0; // 0 => unbuffered, 1 => buffered
uint8_t disconnectOthers = 0; // 0 => no, 1 => yes
uint32_t length = 0;
};

Expand Down
20 changes: 15 additions & 5 deletions src/dmdServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ using namespace std;

DMDUtil::DMD* pDmd;
uint32_t currentThreadId = 0;
bool disconnectOtherClients = false;
std::vector<uint32_t> threads;
bool opt_verbose = false;
bool opt_fixedAltColorPath = false;
Expand Down Expand Up @@ -74,7 +75,8 @@ void run(sockpp::tcp_socket sock, uint32_t threadId)
DMDUtil::DMD::StreamHeader* pStreamHeader = (DMDUtil::DMD::StreamHeader*)malloc(sizeof(DMDUtil::DMD::StreamHeader));
ssize_t n;

while ((n = sock.read_n(buffer, sizeof(DMDUtil::DMD::StreamHeader))) > 0)
while ((n = sock.read_n(buffer, sizeof(DMDUtil::DMD::StreamHeader))) > 0 &&
(!disconnectOtherClients || threadId == currentThreadId))
{
if (n == sizeof(DMDUtil::DMD::StreamHeader))
{
Expand All @@ -90,6 +92,13 @@ void run(sockpp::tcp_socket sock, uint32_t threadId)
if (pStreamHeader->buffered) DMDUtil::Log("Next data will be buffered");
}

// Only the current (most recent) thread is allowed to disconnect other clients.
if (threadId == currentThreadId && pStreamHeader->disconnectOthers)
{
if (opt_verbose) DMDUtil::Log("Other clients will be disconnected");
disconnectOtherClients = true;
}

switch (pStreamHeader->mode)
{
case DMDUtil::DMD::Mode::Data:
Expand Down Expand Up @@ -171,8 +180,8 @@ void run(sockpp::tcp_socket sock, uint32_t threadId)
}
}

// Display a buffered frame or clear the display.
if (!pDmd->QueueBuffer())
// Display a buffered frame or clear the display on disconnect of the current thread.
if (threadId == currentThreadId && !pDmd->QueueBuffer())
{
// Clear the DMD by sending a black screen.
// Fixed dimension of 128x32 should be OK for all devices.
Expand All @@ -181,7 +190,8 @@ void run(sockpp::tcp_socket sock, uint32_t threadId)
}

threads.erase(remove(threads.begin(), threads.end(), threadId), threads.end());
currentThreadId = threads.back();
currentThreadId = (threads.size() >= 1) ? threads.back() : 0;
if (threads.size() <= 1) disconnectOtherClients = false;

free(pStreamHeader);
}
Expand Down Expand Up @@ -297,7 +307,7 @@ int main(int argc, char* argv[])
else
{
if (opt_verbose) DMDUtil::Log("New DMD client connected");
currentThreadId = threadId++;
currentThreadId = ++threadId;
threads.push_back(currentThreadId);
// Create a thread and transfer the new stream to it.
thread thr(run, std::move(sock), currentThreadId);
Expand Down

0 comments on commit 5d88284

Please sign in to comment.