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:
parent
df3d5728d3
commit
c0a698e8a3
5 changed files with 49 additions and 27 deletions
|
@ -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"]
|
||||||
|
|
7
royalnet/network/message.py
Normal file
7
royalnet/network/message.py
Normal 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
|
|
@ -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}")
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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:
|
||||||
|
|
Loading…
Reference in a new issue