]> www.average.org Git - loctrkd.git/commitdiff
support subscriptions on the client side
authorEugene Crosser <crosser@average.org>
Fri, 6 May 2022 22:05:21 +0000 (00:05 +0200)
committerEugene Crosser <crosser@average.org>
Fri, 6 May 2022 22:05:21 +0000 (00:05 +0200)
gps303/wsgateway.py
webdemo/index.html

index c7f96524e98573463ac25318d0599421ccab28cb..f2c6596c3e6a584c1280a9d3c2025e6ee265ebae 100644 (file)
@@ -1,5 +1,6 @@
 """ Websocket Gateway """
 
+from json import loads
 from logging import getLogger
 from socket import socket, AF_INET6, SOCK_STREAM, SOL_SOCKET, SO_REUSEADDR
 from time import time
@@ -63,7 +64,7 @@ def try_http(data, fd, e):
                     return (
                         f"{proto} 500 File not found\r\n"
                         f"Content-Type: text/plain\r\n\r\n"
-                        f'HTML file could not be opened\r\n'.encode()
+                        f"HTML file could not be opened\r\n".encode()
                     )
             else:
                 return (
@@ -90,6 +91,8 @@ class Client:
         self.addr = addr
         self.ws = WSConnection(ConnectionType.SERVER)
         self.ws_data = b""
+        self.ready = False
+        self.imeis = set()
 
     def close(self):
         log.debug("Closing fd %d", self.sock.fileno())
@@ -122,6 +125,7 @@ class Client:
                 e,
             )
             self.ws_data = try_http(data, self.sock.fileno(), e)
+            self.write()  # TODO this is a hack
             log.debug("Sending HTTP response to %d", self.sock.fileno())
             msgs = None
         else:
@@ -131,25 +135,33 @@ class Client:
                     log.debug("WebSocket upgrade on fd %d", self.sock.fileno())
                     # self.ws_data += self.ws.send(event.response())  # Why not?!
                     self.ws_data += self.ws.send(AcceptConnection())
+                    self.ready = True
                 elif isinstance(event, (CloseConnection, Ping)):
                     log.debug("%s on fd %d", event, self.sock.fileno())
                     self.ws_data += self.ws.send(event.response())
                 elif isinstance(event, TextMessage):
                     # TODO: save imei "subscription"
                     log.debug("%s on fd %d", event, self.sock.fileno())
-                    msgs.append(event.data)
+                    msg = loads(event.data)
+                    msgs.append(msg)
+                    if msg.get("type", None) == "subscribe":
+                        self.imeis = set(msg.get("imei", []))
+                        log.debug(
+                            "subs list on fd %s is %s",
+                            self.sock.fileno(),
+                            self.imeis,
+                        )
                 else:
                     log.warning("%s on fd %d", event, self.sock.fileno())
-        if self.ws_data:  # Temp hack
-            self.write()
         return msgs
 
     def wants(self, imei):
+        log.debug("wants %s? set is %s on fd %d", imei, self.imeis, self.sock.fileno())
         return True  # TODO: check subscriptions
 
     def send(self, message):
-        # TODO: filter only wanted imei got from the client
-        self.ws_data += self.ws.send(Message(data=message.json))
+        if self.ready and message.imei in self.imeis:
+            self.ws_data += self.ws.send(Message(data=message.json))
 
     def write(self):
         if self.ws_data:
@@ -190,6 +202,7 @@ class Clients:
         result = []
         for msg in msgs:
             log.debug("Received: %s", msg)
+            result.append(msg)
         return result
 
     def send(self, msg):
@@ -250,9 +263,11 @@ def runserver(conf):
                     if received is None:
                         log.debug("Client gone from fd %d", sk)
                         tostop.append(sk)
+                        towait.discard(fd)
                     else:
                         for msg in received:
                             log.debug("Received from %d: %s", sk, msg)
+                        towrite.add(sk)
                 elif fl & zmq.POLLOUT:
                     log.debug("Write now open for fd %d", sk)
                     towrite.add(sk)
index f356f96339b3fc784ee38e2d29710cc1813b0831..2b3edd7958daff88e5962f9515aa77fe81573dd7 100644 (file)
@@ -8,12 +8,20 @@
        <script type="text/javascript">
                const urlParams = new URLSearchParams(window.location.search);
                const qimei = urlParams.get("imei");
-               const wsproto = window.protocol === "https" ? "wss" : "ws";
-               const wshost = window.hostname ? window.hostname : "localhost";
-               const wsport = window.port ? window.port : 5049;
+
+               const ourl = new URL(window.location);
+               const wsproto = ourl.protocol === "https" ? "wss" : "ws";
+               const wshost = ourl.hostname ? ourl.hostname : "localhost";
+               const wsport = ourl.port ? ourl.port : 5049;
+
+               const imeis = new Set();
 
                var sts;
                var ws;
+               var imei;
+               var send;
+               var subslist;
+               var tstamp;
                var map;
                var markers;
                var icon;
@@ -24,6 +32,9 @@
                        sts.innerHTML = "uninitialized";
                        imei = document.getElementById("imei");
                        send = document.getElementById("send");
+                       clear = document.getElementById("clear");
+                       subslist = document.getElementById("subslist");
+                       tstamp = document.getElementById("tstamp");
                        if (qimei) {
                                imei.value = qimei;
                        }
                        sts.innerHTML = "open";
                        imei.disabled = false;
                        send.disabled = false;
-                       if (imei.value) {
-                               sendIMEI();
-                       }
+                       clear.disabled = false;
+                       sendIMEI();
                }
                function ws_onmessage(event) {
                        console.log("message " + event.data);
                        msg = JSON.parse(event.data)
+                       tstamp.innerHTML = msg.devtime;
                        set_marker(+msg.longitude, +msg.latitude);
                }
                function ws_onerror(event) {
                        sts.innerHTML = "closed";
                        imei.disabled = true;
                        send.disabled = true;
+                       clear.disabled = true;
                        setTimeout(open_ws, 5000);
                }
 
-               function sendIMEI() {
-                       console.log("sending " + imei.value);
+               function sendIMEI(do_clear) {
+                       if (do_clear) {
+                               imeis.clear();
+                       } else {
+                               if (imei.value) {
+                                       imeis.add(imei.value);
+                               }
+                       }
+                       const imstr = Array.from(imeis).join(",");
+                       document.title = imstr;
+                       subslist.innerHTML = imstr;
                        var msg = {
-                               imei: imei.value,
+                               imei: Array.from(imeis),
                                type: "subscribe",
                                date: Date.now()
                        };
+                       console.log("sending" + JSON.stringify(msg));
                        ws.send(JSON.stringify(msg));
-                       document.title = imei.value;
                        imei.value = "";
                }
 
                function handleKey(evt) {
                        if (evt.keyCode === 13 || evt.keyCode === 14) {
                                if (!imei.disabled) {
-                                       sendIMEI();
+                                       sendIMEI(false);
                                }
                        }
                }
                 size="16" maxlength="16" placeholder="Enter IMEI"
                 autocomplete="off" onkeyup="handleKey(event)">
                <input type="button" id="send" name="send" value="Send"
-                onclick="sendIMEI()" disabled>
+                onclick="sendIMEI(false)" disabled>
+               <input type="button" id="clear" name="clear" value="Clear"
+                onclick="sendIMEI(true)" disabled>
+               <span id="subslist"></span>
+               <span id="tstamp" style="float:right"></span>
        </div>
        <div style="width:100%; height:97%" id="map"></div>
        <div style="width:100%; height:1%" id="sts"></div>