1234
This commit is contained in:
@@ -10,7 +10,7 @@
|
||||
|
||||
OBJECTIVE:
|
||||
|
||||
A simple namespace to test the Socket.IO app with a simple echo utility.
|
||||
A namespace to
|
||||
|
||||
REFERENCES:
|
||||
|
||||
@@ -32,50 +32,18 @@
|
||||
|
||||
# To make sibling directories accessible for imports:
|
||||
import sys
|
||||
sys.path.append("../wsio")
|
||||
sys.path.append(".")
|
||||
sys.path.append("..")
|
||||
|
||||
# System-level activities:
|
||||
import io
|
||||
import os
|
||||
import random
|
||||
|
||||
# My utils:
|
||||
from utils_v2.string import json
|
||||
from utils_v2.string import regex
|
||||
from utils_v2.system import files
|
||||
from utils_v2.date_time import date_time
|
||||
from utils_v2.database.async_mongo_v2 import AsyncMongo
|
||||
from utils_v2.queue.kafka.controllers.async_kafka import ConsumerKafka, get_ssl_context
|
||||
from utils_v2.cache.async_redis_cache_v3 import AsyncRedisCache
|
||||
from utils_v2.serialization.json_serializer import JSONSerializer
|
||||
|
||||
# To make HTTP calls:
|
||||
import httpx
|
||||
|
||||
# To work with date and time:
|
||||
import datetime
|
||||
import time
|
||||
|
||||
# Models:
|
||||
from models.core.user import CoreUserInfoModel
|
||||
from models.finstitutions.trading.ticks import TradingTick
|
||||
|
||||
# To work with SocketIO:
|
||||
import socket
|
||||
import socketio
|
||||
|
||||
# To maintain the app's state:
|
||||
from wsio_v2.app_state import AppState
|
||||
|
||||
# For asynchronous activities:
|
||||
import asyncio
|
||||
|
||||
# To work with various datatypes:
|
||||
from typing import List
|
||||
|
||||
# Debugging:
|
||||
from icecream import IceCreamDebugger
|
||||
# For pre-modelled responses:
|
||||
from utils_v2.api.codes import HttpCodes, StatusCodes
|
||||
from utils_v2.api.response import ResponseModel
|
||||
|
||||
|
||||
# *****************************************************************************************************************
|
||||
@@ -112,20 +80,102 @@ class EchoNamespace(socketio.AsyncNamespace):
|
||||
namespace: str,
|
||||
app_state: AppState,
|
||||
):
|
||||
|
||||
"""
|
||||
To set up the namespace that will handle tick data.
|
||||
:param namespace: The string that defines the path of the namespace. E.g.: "/test".
|
||||
:param app_state: The AppState that defines the state of the app and carries any custom variables that will be
|
||||
needed across various namespaces. It's a good way to pass instances of database connections and other shared
|
||||
variables.
|
||||
"""
|
||||
|
||||
super().__init__(namespace)
|
||||
self.app_state = app_state
|
||||
self.app_state.printer("Registered!")
|
||||
|
||||
async def on_connect(self, sid, environ, *args):
|
||||
self.app_state.printer("On Connect", sid)
|
||||
async def on_connect(self, sid, environ, *args) -> bool | None:
|
||||
|
||||
"""
|
||||
The handler that validates and accepts or rejects incoming connection requests.
|
||||
:param sid: The socketio session id.
|
||||
:param environ: The environment information.
|
||||
:param args: The arguments passed to the handler.
|
||||
:returns: True if the connection was accepted, else False.
|
||||
"""
|
||||
|
||||
self.app_state.printer("Connection Attempt", sid)
|
||||
|
||||
async def on_disconnect(self, sid, reason, *args):
|
||||
|
||||
"""
|
||||
The handler that notes down that the user has been disconnected and frees up any relevant resources.
|
||||
:param sid: The socketio session id.
|
||||
:param reason: The reason for termination.
|
||||
:param args: The arguments passed to the handler.
|
||||
:returns: None.
|
||||
"""
|
||||
|
||||
self.app_state.printer("On Disconnect", sid)
|
||||
|
||||
async def on_echo(self, sid, data):
|
||||
|
||||
"""
|
||||
A test event that can be used to see if the namespace is up and running, or not.
|
||||
:param sid: The socketio session id.
|
||||
:param data: The data sent by the client.
|
||||
:returns: None.
|
||||
"""
|
||||
|
||||
self.app_state.printer("Event", sid, data, type(data).__name__)
|
||||
await self.emit("echo", data, to = sid)
|
||||
|
||||
async def on_set_watchlist(self, sid, data) -> dict:
|
||||
|
||||
"""
|
||||
To handle the request to set the watchlist for a particular user.
|
||||
:param sid: The socketio session id.
|
||||
:param data: The data sent by the client.
|
||||
:returns: None.
|
||||
"""
|
||||
|
||||
self.app_state.printer("Setting Watchlist", sid)
|
||||
|
||||
# Start by assuming success:
|
||||
response = ResponseModel(
|
||||
status_code = StatusCodes.OK,
|
||||
message = "Watchlist set successfully.",
|
||||
data = None
|
||||
)
|
||||
|
||||
# Prepare a list of tickers from the request:
|
||||
tickers_list = []
|
||||
|
||||
# Remove the user from all rooms (tickers):
|
||||
if response.success:
|
||||
try:
|
||||
rooms = self.rooms(sid)
|
||||
for room in rooms:
|
||||
if room != sid: # ... Don't remove them from their private room.
|
||||
await self.leave_room(sid, room)
|
||||
except Exception as e:
|
||||
self.app_state.printer("EXCEPTION!", e)
|
||||
response.status_code = StatusCodes.FAILED
|
||||
response.message = "Failed to reset previous watchlist."
|
||||
|
||||
# Now add the user back to just those rooms (tickers) that he has requested:
|
||||
if response.success:
|
||||
try:
|
||||
for room in tickers_list:
|
||||
await self.enter_room(sid, room)
|
||||
except Exception as e:
|
||||
self.app_state.printer("EXCEPTION!", e)
|
||||
response.status_code = StatusCodes.FAILED
|
||||
response.message = "Failed to set new watchlist."
|
||||
|
||||
# Done here:
|
||||
response_dict, response_http_code = response.for_quart()
|
||||
await self.emit("set_watchlist", response_dict, to = sid)
|
||||
|
||||
|
||||
# *****************************************************************************************************************
|
||||
# ***** ****
|
||||
|
||||
Reference in New Issue
Block a user