1
Fork 0
mirror of https://github.com/RYGhub/royalnet.git synced 2024-11-23 19:44:20 +00:00

Do... stuff that i dont even know if it works

This commit is contained in:
Steffo 2019-05-20 00:28:07 +02:00
parent df3d5728d3
commit c0a698e8a3
5 changed files with 49 additions and 27 deletions

View file

@ -1,5 +1,17 @@
from . import audio, bots, commands, database, network, utils, error from . import audio, \
bots, \
commands, \
database, \
network, \
utils, \
error
version = "5.0a7" version = "5.0a7"
__all__ = ["audio", "bots", "commands", "database", "network", "utils", "error"] __all__ = ["audio",
"bots",
"commands",
"database",
"network",
"utils",
"error"]

View file

@ -0,0 +1,7 @@
from ..utils import classdictjanitor
class Message:
"""A Royalnet message. All fields of this class will be converted in a dict."""
# idk use classdictjanitor

View file

@ -91,7 +91,7 @@ class RoyalnetLink:
Raises: Raises:
:py:exc:`royalnet.network.royalnetlink.ConnectionClosedError` if the connection closes.""" :py:exc:`royalnet.network.royalnetlink.ConnectionClosedError` if the connection closes."""
try: try:
jbytes = await self.websocket.recv() jbytes: bytes = await self.websocket.recv()
package: Package = Package.from_json_bytes(jbytes) package: Package = Package.from_json_bytes(jbytes)
except websockets.ConnectionClosed: except websockets.ConnectionClosed:
self.error_event.set() self.error_event.set()
@ -99,7 +99,7 @@ class RoyalnetLink:
self.identify_event.clear() self.identify_event.clear()
log.info(f"Connection to {self.master_uri} was closed.") log.info(f"Connection to {self.master_uri} was closed.")
# What to do now? Let's just reraise. # What to do now? Let's just reraise.
raise ConnectionClosedError("") raise ConnectionClosedError()
assert package.destination == self.nid assert package.destination == self.nid
log.debug(f"Received package: {package}") log.debug(f"Received package: {package}")
return package return package
@ -108,7 +108,11 @@ class RoyalnetLink:
async def identify(self) -> None: async def identify(self) -> None:
log.info(f"Identifying to {self.master_uri}...") log.info(f"Identifying to {self.master_uri}...")
await self.websocket.send(f"Identify {self.nid}:{self.link_type}:{self.secret}") await self.websocket.send(f"Identify {self.nid}:{self.link_type}:{self.secret}")
response_package: dict = await self.receive() response: Package = await self.receive()
assert response.source == "<server>"
if "error" in response.data:
raise ConnectionClosedError(f"Identification error: {response.data['error']}")
assert "success" in response.data
self.identify_event.set() self.identify_event.set()
log.info(f"Identified successfully!") log.info(f"Identified successfully!")
@ -125,11 +129,9 @@ class RoyalnetLink:
await self.send(package) await self.send(package)
log.debug(f"Sent request: {message} -> {destination}") log.debug(f"Sent request: {message} -> {destination}")
await request.event.wait() await request.event.wait()
result: Message = request.data response: dict = request.data
log.debug(f"Received response: {request} -> {result}") log.debug(f"Received response: {request} -> {response}")
if isinstance(result, ServerErrorMessage): return response
raise NetworkError(result, "Server returned error while requesting something")
return result
async def run(self, loops: numbers.Real = math.inf): async def run(self, loops: numbers.Real = math.inf):
"""Blockingly run the Link.""" """Blockingly run the Link."""
@ -153,9 +155,9 @@ class RoyalnetLink:
log.debug(f"Received request {package.source_conv_id}: {package}") log.debug(f"Received request {package.source_conv_id}: {package}")
try: try:
response = await self.request_handler(package.data) response = await self.request_handler(package.data)
assert isinstance(response, Message)
except Exception as exc: except Exception as exc:
response = RequestError(exc=exc) response = {"error": "Exception in request_handler",
"exception": exc.__class__.__name__}
response_package: Package = package.reply(response) response_package: Package = package.reply(response)
await self.send(response_package) await self.send(response_package)
log.debug(f"Replied to request {response_package.source_conv_id}: {response_package}") log.debug(f"Replied to request {response_package.source_conv_id}: {response_package}")

View file

@ -2,7 +2,6 @@ import typing
import websockets import websockets
import re import re
import datetime import datetime
import pickle
import uuid import uuid
import asyncio import asyncio
import logging as _logging import logging as _logging
@ -25,8 +24,8 @@ class ConnectedClient:
"""Has the client sent a valid identification package?""" """Has the client sent a valid identification package?"""
return bool(self.nid) return bool(self.nid)
async def send_server_error(self, reason: str): async def send_service(self, msg_type: str, message: str):
await self.send(Package({"error": reason}, await self.send(Package({"type": msg_type, "service": message},
source="<server>", source="<server>",
destination=self.nid)) destination=self.nid))
@ -60,31 +59,31 @@ class RoyalnetServer:
identify_msg = await websocket.recv() identify_msg = await websocket.recv()
log.debug(f"{websocket.remote_address} identified itself with: {identify_msg}.") log.debug(f"{websocket.remote_address} identified itself with: {identify_msg}.")
if not isinstance(identify_msg, str): if not isinstance(identify_msg, str):
await websocket.send(connected_client.send_server_error("Invalid identification message (not a str)")) await websocket.send(connected_client.send_service("error", "Invalid identification message (not a str)"))
return return
identification = re.match(r"Identify ([^:\s]+):([^:\s]+):([^:\s]+)", identify_msg) identification = re.match(r"Identify ([^:\s]+):([^:\s]+):([^:\s]+)", identify_msg)
if identification is None: if identification is None:
await websocket.send(connected_client.send_server_error("Invalid identification message (regex failed)")) await websocket.send(connected_client.send_service("error", "Invalid identification message (regex failed)"))
return return
secret = identification.group(3) secret = identification.group(3)
if secret != self.required_secret: if secret != self.required_secret:
await websocket.send(connected_client.send_server_error("Invalid secret")) await websocket.send(connected_client.send_service("error", "Invalid secret"))
return return
# Identification successful # Identification successful
connected_client.nid = identification.group(1) connected_client.nid = identification.group(1)
connected_client.link_type = identification.group(2) connected_client.link_type = identification.group(2)
self.identified_clients.append(connected_client) self.identified_clients.append(connected_client)
log.debug(f"{websocket.remote_address} identified successfully as {connected_client.nid} ({connected_client.link_type}).") log.debug(f"{websocket.remote_address} identified successfully as {connected_client.nid} ({connected_client.link_type}).")
await connected_client.send(Package(IdentifySuccessfulMessage(), connected_client.nid, "__master__")) await connected_client.send_service("success", "Identification successful!")
log.debug(f"{connected_client.nid}'s identification confirmed.") log.debug(f"{connected_client.nid}'s identification confirmed.")
# Main loop # Main loop
while True: while True:
# Receive packages # Receive packages
raw_pickle = await websocket.recv() raw_bytes = await websocket.recv()
package: Package = pickle.loads(raw_pickle) package: Package = Package.from_json_bytes(raw_bytes)
log.debug(f"Received package: {package}") log.debug(f"Received package: {package}")
# Check if the package destination is the server itself. # Check if the package destination is the server itself.
if package.destination == "__master__": if package.destination == "<server>":
# TODO: do stuff # TODO: do stuff
pass pass
# Otherwise, route the package to its destination # Otherwise, route the package to its destination
@ -101,7 +100,7 @@ class RoyalnetServer:
A :py:class:`list` of :py:class:`ConnectedClients` to send the package to.""" A :py:class:`list` of :py:class:`ConnectedClients` to send the package to."""
# Parse destination # Parse destination
# Is it nothing? # Is it nothing?
if package.destination == "NULL": if package.destination == "<none>":
return [] return []
# Is it a valid nid? # Is it a valid nid?
try: try:
@ -118,7 +117,10 @@ class RoyalnetServer:
destinations = self.find_destination(package) destinations = self.find_destination(package)
log.debug(f"Routing package: {package} -> {destinations}") log.debug(f"Routing package: {package} -> {destinations}")
for destination in destinations: for destination in destinations:
specific_package = Package(package.data, destination.nid, package.source, # This may have some consequences
specific_package = Package(package.data,
source=package.source,
destination=destination.nid,
source_conv_id=package.source_conv_id, source_conv_id=package.source_conv_id,
destination_conv_id=package.destination_conv_id) destination_conv_id=package.destination_conv_id)
await destination.send(specific_package) await destination.send(specific_package)
@ -127,7 +129,7 @@ class RoyalnetServer:
await websockets.serve(self.listener, host=self.address, port=self.port) await websockets.serve(self.listener, host=self.address, port=self.port)
async def start(self): async def start(self):
log.debug(f"Starting main server loop for __master__ on ws://{self.address}:{self.port}") log.debug(f"Starting main server loop for <server> on ws://{self.address}:{self.port}")
# noinspection PyAsyncCall # noinspection PyAsyncCall
self._loop.create_task(self.serve()) self._loop.create_task(self.serve())
# Just to be sure it has started on Linux # Just to be sure it has started on Linux

View file

@ -1,6 +1,5 @@
import typing import typing
import asyncio import asyncio
from ..network import Message, Reply
from .command import Command from .command import Command
from .commandargs import CommandArgs from .commandargs import CommandArgs
if typing.TYPE_CHECKING: if typing.TYPE_CHECKING:
@ -26,7 +25,7 @@ class Call:
text: The text to be sent, possibly formatted in the weird undescribed markup that I'm using.""" text: The text to be sent, possibly formatted in the weird undescribed markup that I'm using."""
raise NotImplementedError() raise NotImplementedError()
async def net_request(self, message, destination: str) -> Reply: async def net_request(self, message, destination: str) -> dict:
"""Send data through a :py:class:`royalnet.network.RoyalnetLink` and wait for a :py:class:`royalnet.network.Reply`. """Send data through a :py:class:`royalnet.network.RoyalnetLink` and wait for a :py:class:`royalnet.network.Reply`.
Parameters: Parameters: