1
0
mirror of https://github.com/DCC-EX/CommandStation-EX.git synced 2025-01-30 22:23:07 +01:00

websockets broadcast

This commit is contained in:
Asbelos 2025-01-16 08:37:38 +00:00
parent 2591d100ca
commit c4e2146bd1
3 changed files with 47 additions and 1 deletions

View File

@ -45,6 +45,7 @@ template<typename... Targs> void CommandDistributor::broadcastReply(clientType t
broadcastBufferWriter->flush(); broadcastBufferWriter->flush();
StringFormatter::send(broadcastBufferWriter, msg...); StringFormatter::send(broadcastBufferWriter, msg...);
broadcastToClients(type); broadcastToClients(type);
if (type==COMMAND_TYPE) broadcastToClients(WEBSOCKET_TYPE);
} }
#else #else
// on a single USB connection config, write direct to Serial and ignore flush/shove // on a single USB connection config, write direct to Serial and ignore flush/shove
@ -76,6 +77,7 @@ void CommandDistributor::parse(byte clientId,byte * buffer, RingStream * stream
auto websock=Websockets::checkConnectionString(clientId,buffer,stream); auto websock=Websockets::checkConnectionString(clientId,buffer,stream);
if (websock) { if (websock) {
clients[clientId]=WEBSOCK_CONNECTING_TYPE; clients[clientId]=WEBSOCK_CONNECTING_TYPE;
// websockets will have replied already
return; return;
} }
if (buffer[0] == '<') if (buffer[0] == '<')
@ -149,7 +151,7 @@ void CommandDistributor::broadcastToClients(clientType type) {
for (byte clientId=0; clientId<sizeof(clients); clientId++) { for (byte clientId=0; clientId<sizeof(clients); clientId++) {
if (clients[clientId]==type) { if (clients[clientId]==type) {
//DIAG(F("CD mark client %d"), clientId); //DIAG(F("CD mark client %d"), clientId);
ring->mark(clientId); ring->mark(clientId | (type==WEBSOCKET_TYPE? Websockets::WEBSOCK_CLIENT_MARKER : 0));
ring->print(broadcastBufferWriter->getString()); ring->print(broadcastBufferWriter->getString());
//DIAG(F("CD commit client %d"), clientId); //DIAG(F("CD commit client %d"), clientId);
ring->commit(); ring->commit();

View File

@ -0,0 +1,41 @@
<html>
<!-- Minimalist test page for the DCCEX websocket API.-->
<head>
<script>
let socket = new WebSocket("ws://192.168.1.242:2560","DCCEX");
// send message from the form
var sender = function() {
var msg=document.getElementById('message').value;
socket.send(msg);
}
// message received - show the message in div#messages
socket.onmessage = function(event) {
let message = event.data;
let messageElem = document.createElement('div');
messageElem.textContent = message;
document.getElementById('messages').prepend(messageElem);
}
socket.onerror = function(event) {
let message = event.data;
let messageElem = document.createElement('div');
messageElem.textContent = message;
document.getElementById('messages').prepend(messageElem);
}
</script>
</head>
<body>
This is a minimalist test page for the DCCEX websocket API.
It demonstrates the Websocket connection and how to send
or receive websocket traffic.
The connection string must be edited to address your command station
correctly.<p>
<!-- message form -->
<input type="text" id="message">
<input type="button" value="Send" onclick="sender();">
<!-- div with messages -->
<div id="messages"></div>
</body>
</html>

View File

@ -28,6 +28,9 @@
CommandDistributor pass it to this code CommandDistributor pass it to this code
checkConnectionString() to check for an HTTP checkConnectionString() to check for an HTTP
protocol GET requesting a change to websocket protocol. protocol GET requesting a change to websocket protocol.
[Note that the WifiInboundHandler has a shortcut to detecting this so that
it does not need to use up 500+ bytes of RAM just to get at the one parameter that
actually means something.]
If that is found, the relevant answer is generated and queued and If that is found, the relevant answer is generated and queued and
the CommandDistributor marks this client as a websocket client awaiting connection. the CommandDistributor marks this client as a websocket client awaiting connection.
Once the outbound handshake has completed, the CommandDistributor promotes the client Once the outbound handshake has completed, the CommandDistributor promotes the client