Add live (redis and websockets)
Add modernised ipynb_tools Add scheduler Fix crs in settings Lots of small fixes
This commit is contained in:
parent
461c31fb6f
commit
47df53f4d1
15 changed files with 1614 additions and 61 deletions
|
@ -2,14 +2,16 @@
|
|||
Geographical json stores, served under /gj
|
||||
Used for displaying features on maps
|
||||
"""
|
||||
from json import JSONDecodeError
|
||||
import logging
|
||||
from typing import Annotated
|
||||
from asyncio import CancelledError
|
||||
|
||||
from fastapi import FastAPI, HTTPException, Response, status, responses, Header
|
||||
from fastapi import (FastAPI, HTTPException, Response, Header, WebSocket, WebSocketDisconnect,
|
||||
status, responses)
|
||||
|
||||
from .redis_tools import store as redis_store
|
||||
# from gisaf.live import live_server
|
||||
from .live import live_server
|
||||
from .registry import registry
|
||||
|
||||
|
||||
|
@ -19,28 +21,54 @@ api = FastAPI(
|
|||
default_response_class=responses.ORJSONResponse,
|
||||
)
|
||||
|
||||
@api.get('/live/{store}')
|
||||
async def live_layer(store: str):
|
||||
class ConnectionManager:
|
||||
active_connections: list[WebSocket]
|
||||
def __init__(self):
|
||||
self.active_connections = []
|
||||
|
||||
async def connect(self, websocket: WebSocket):
|
||||
await websocket.accept()
|
||||
self.active_connections.append(websocket)
|
||||
|
||||
def disconnect(self, websocket: WebSocket):
|
||||
self.active_connections.remove(websocket)
|
||||
|
||||
async def send_personal_message(self, message: str, websocket: WebSocket):
|
||||
await websocket.send_text(message)
|
||||
|
||||
async def broadcast(self, message: str):
|
||||
for connection in self.active_connections:
|
||||
await connection.send_text(message)
|
||||
|
||||
manager = ConnectionManager()
|
||||
|
||||
@api.websocket('/live/{store}')
|
||||
async def live_layer(store: str, websocket: WebSocket):
|
||||
"""
|
||||
Websocket for live layer updates
|
||||
"""
|
||||
ws = web.WebSocketResponse()
|
||||
await ws.prepare(request)
|
||||
async for msg in ws:
|
||||
if msg.type == WSMsgType.TEXT:
|
||||
if msg.data == 'close':
|
||||
await ws.close()
|
||||
await websocket.accept()
|
||||
try:
|
||||
while True:
|
||||
try:
|
||||
msg_data = await websocket.receive_json()
|
||||
except JSONDecodeError:
|
||||
msg_text = await websocket.receive_text()
|
||||
if msg_text == 'close':
|
||||
await websocket.close()
|
||||
continue
|
||||
# else:
|
||||
if 'message' in msg_data:
|
||||
if msg_data['message'] == 'subscribeLiveLayer':
|
||||
live_server.add_subscription(websocket, store)
|
||||
elif msg_data['message'] == 'unsubscribeLiveLayer':
|
||||
live_server.remove_subscription(websocket, store)
|
||||
else:
|
||||
msg_data = msg.json()
|
||||
if 'message' in msg_data:
|
||||
if msg_data['message'] == 'subscribeLiveLayer':
|
||||
live_server.add_subscription(ws, store)
|
||||
elif msg_data['message'] == 'unsubscribeLiveLayer':
|
||||
live_server.remove_subscription(ws, store)
|
||||
elif msg.type == WSMsgType.ERROR:
|
||||
logger.exception(ws.exception())
|
||||
logger.debug('websocket connection closed')
|
||||
return ws
|
||||
logger.warning(f'Got websocket message with no message field: {msg_data}')
|
||||
except WebSocketDisconnect:
|
||||
logger.debug('Websocket disconnected')
|
||||
|
||||
# logger.debug('websocket connection closed')
|
||||
|
||||
@api.get('/{store_name}')
|
||||
async def get_geojson(store_name,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue