diff --git a/README.md b/README.md
index 1350f7f..3bcac97 100644
--- a/README.md
+++ b/README.md
@@ -5,14 +5,15 @@
```plantuml
@startuml
-participant FE as "Frontend" << React >>
+participant FE as "Frontend" << JavaScript >>
+participant WS as "WS Server" << Python >>
participant Funnel as "Funnel" << Python >>
participant Segments as "ServeSegments" << Go >>
participant CurrentTime as "ServeCurrentTime" << NodeJS >>
activate FE #hotpink
FE -> FE: Load page
- FE -> Funnel: WS Connect
+ FE -> WS: WS Connect
loop #ivory
activate Funnel #gold
@@ -44,7 +45,8 @@ activate FE #hotpink
return HH:MM:SS.ms
return ms
- Funnel -> FE: WS: Send formatted time
+ Funnel -> WS: WS: Send complete time
+ WS --> FE: WS: Send complete time
deactivate Funnel
end
deactivate FE
diff --git a/src/frontend/index.html b/src/frontend/index.html
new file mode 100644
index 0000000..4bc2ddd
--- /dev/null
+++ b/src/frontend/index.html
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+ Document
+
+
+
+ Hello world
+
+
+ -
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/funnel/main.py b/src/funnel/main.py
index 6be79a2..f875b4e 100644
--- a/src/funnel/main.py
+++ b/src/funnel/main.py
@@ -1,9 +1,12 @@
import asyncio
+import json
import time
from contextlib import asynccontextmanager
from typing import AsyncGenerator, Optional
import grpc
+import websockets
+from websockets.server import WebSocketServerProtocol
from stubs.serve_segments_pb2 import (
GetHoursRequest,
@@ -21,6 +24,8 @@ SERVE_CURRENTTIME_HOST = "localhost"
SERVE_CURRENTTIME_PORT = 50000
SERVE_SEGMENTS_HOST = "localhost"
SERVE_SEGMENTS_PORT = 50001
+WS_HOST = "localhost"
+WS_PORT = 5000
TIMEZONE = "Europe/Zagreb"
@@ -61,33 +66,62 @@ async def get_milliseconds(stub: ServeSegmentsStub) -> Optional[int]:
async def main():
- async with get_serve_segments_stub() as stub:
- while True:
- t = time.perf_counter()
+ ws_uri = f"ws://{WS_HOST}:{WS_PORT}"
+ async with websockets.connect(uri=ws_uri) as websocket:
+ async with get_serve_segments_stub() as stub:
+ while True:
+ t = time.perf_counter()
- # create tasks
- task_hours = asyncio.create_task(get_hours(stub))
- task_minutes = asyncio.create_task(get_minutes(stub))
- task_seconds = asyncio.create_task(get_seconds(stub))
- task_milliseconds = asyncio.create_task(get_milliseconds(stub))
+ # create tasks
+ task_hours = asyncio.create_task(get_hours(stub))
+ task_minutes = asyncio.create_task(get_minutes(stub))
+ task_seconds = asyncio.create_task(get_seconds(stub))
+ task_milliseconds = asyncio.create_task(get_milliseconds(stub))
- # exec tasks asynchronously
- await asyncio.gather(
- task_hours, task_minutes, task_seconds, task_milliseconds
- )
+ # exec tasks asynchronously
+ await asyncio.gather(
+ task_hours, task_minutes, task_seconds, task_milliseconds
+ )
- # get results
- hours = task_hours.result()
- minutes = task_minutes.result()
- seconds = task_seconds.result()
- milliseconds = task_milliseconds.result()
+ # get results
+ hours = task_hours.result()
+ minutes = task_minutes.result()
+ seconds = task_seconds.result()
+ milliseconds = task_milliseconds.result()
+ formatted_time = (
+ f"{hours:02d}:{minutes:02d}:{seconds:02d}:{milliseconds:03d}"
+ )
+ comm_cycle = time.perf_counter() - t
- t = time.perf_counter() - t
+ data = {
+ "hours": hours,
+ "minutes": minutes,
+ "seconds": seconds,
+ "milliseconds": milliseconds,
+ "formattedTime": formatted_time,
+ "commCycle": comm_cycle,
+ "commCycleStr": f"{comm_cycle:0.4f}",
+ }
- print(
- f"RESULT: {hours:02d}:{minutes:02d}:{seconds:02d}:{milliseconds:03d}, T: {t}"
- )
+ await websocket.send(json.dumps(data))
+ await websocket.recv()
+
+ # time.sleep(0.5)
+
+ print(f"RESULT: {formatted_time}, T: {comm_cycle}")
+
+
+async def send_ws_message():
+ ws_uri = f"ws://{WS_HOST}:{WS_PORT}"
+ async with websockets.connect(ws_uri) as websocket:
+ data = {
+ "message": "some text",
+ "value": 12345,
+ }
+
+ await websocket.send(json.dumps(data))
if __name__ == "__main__":
asyncio.run(main())
+ # asyncio.run(send_ws_message())
diff --git a/src/funnel/requirements.txt b/src/funnel/requirements.txt
index 221b96b..18cda57 100644
--- a/src/funnel/requirements.txt
+++ b/src/funnel/requirements.txt
@@ -1,3 +1,4 @@
pydantic
grpcio
grpcio-tools
+websockets
diff --git a/src/funnel/ws_server.py b/src/funnel/ws_server.py
new file mode 100644
index 0000000..589449e
--- /dev/null
+++ b/src/funnel/ws_server.py
@@ -0,0 +1,37 @@
+import asyncio
+import json
+import websockets
+from websockets import broadcast
+from websockets.server import WebSocketServerProtocol
+
+WS_HOST = "localhost"
+WS_PORT = 5000
+
+connected_clients = set()
+
+
+async def ws_handler(websocket: WebSocketServerProtocol):
+ connected_clients.add(websocket)
+ print("Client add: ", websocket)
+
+ try:
+ async for message in websocket:
+ broadcast(connected_clients, message)
+ # await websocket.send(f"Are you talking to me? {message}")
+ finally:
+ connected_clients.remove(websocket)
+ print("Client remove: ", websocket)
+
+
+async def main():
+ print(f"Starting WS server on {WS_HOST}:{WS_PORT}")
+ async with websockets.serve(
+ ws_handler=ws_handler,
+ host=WS_HOST,
+ port=WS_PORT,
+ ):
+ await asyncio.Future() # run forever
+
+
+if __name__ == "__main__":
+ asyncio.run(main())