Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ humanize = ">=2.6.0"
maxminddb = "*"
oauthlib = "*"
prometheus_client = "*"
proxy-protocol = "*"
pyjwt = {version = ">=2.4.0", extras = ["crypto"]}
pyyaml = "*"
sortedcontainers = "*"
Expand Down
114 changes: 51 additions & 63 deletions Pipfile.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

37 changes: 9 additions & 28 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
from server.health import HealthServer
from server.player_service import PlayerService
from server.profiler import Profiler
from server.protocol import QDataStreamProtocol, SimpleJsonProtocol
from server.timing import datetime_now


Expand Down Expand Up @@ -115,34 +114,16 @@ def done_handler(sig: int, frame):

await instance.start_services()

PROTO_CLASSES = {
QDataStreamProtocol.__name__: QDataStreamProtocol,
SimpleJsonProtocol.__name__: SimpleJsonProtocol
}
for cfg in config.LISTEN:
try:
host = cfg["ADDRESS"]
port = cfg["PORT"]
proto_class_name = cfg["PROTOCOL"]
name = cfg.get("NAME")
proxy = cfg.get("PROXY", False)

proto_class = PROTO_CLASSES[proto_class_name]

await instance.listen(
address=(host, port),
name=name,
protocol_class=proto_class,
proxy=proxy
)
except Exception as e:
raise RuntimeError(f"Error with server instance config: {cfg}") from e

if not instance.contexts:
raise RuntimeError(
"The server was not configured to listen on any ports! Check the "
"config file and try again."
try:
await instance.listen(
address=(config.WS_HOST, config.WS_PORT),
path=config.WS_PATH,
)
except Exception as e:
raise RuntimeError(
f"Error starting WebSocket listener on "
f"{config.WS_HOST}:{config.WS_PORT}{config.WS_PATH}"
) from e

server.metrics.info.info({
"version": info.VERSION,
Expand Down
12 changes: 4 additions & 8 deletions minikube-example.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,8 @@ spec:
selector:
app: faf-lobby
ports:
- port: 8001
name: qstream
- port: 8002
name: simplejson
- port: 8003
name: websocket
---
apiVersion: apps/v1
kind: Deployment
Expand Down Expand Up @@ -44,10 +42,8 @@ spec:
name: control
- containerPort: 2000
name: health
- containerPort: 8001
name: qstream
- containerPort: 8002
name: simplejson
- containerPort: 8003
name: websocket
env:
- name: CONFIGURATION_FILE
value: /config/config.yaml
Expand Down
18 changes: 6 additions & 12 deletions server/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,6 @@
from .oauth_service import OAuthService
from .party_service import PartyService
from .player_service import PlayerService
from .protocol import Protocol, QDataStreamProtocol
from .rating_service.rating_service import RatingService
from .servercontext import ServerContext
from .stats.game_stats_service import GameStatsService
Expand Down Expand Up @@ -258,30 +257,25 @@ async def listen(
self,
address: tuple[str, int],
name: Optional[str] = None,
protocol_class: type[Protocol] = QDataStreamProtocol,
proxy: bool = False,
path: str = "/",
) -> ServerContext:
"""
Start listening on a new address.
Start listening for WebSocket connections on a new address.

# Params
- `address`: Tuple indicating the host, port to listen on.
- `name`: String used to identify this context in log messages. The
default is to use the `protocol_class` name.
- `protocol_class`: The protocol class implementation to use.
- `proxy`: Boolean indicating whether or not to use the PROXY protocol.
See: https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt
- `name`: String used to identify this context in log messages.
- `path`: HTTP path on which to expose the WebSocket endpoint.
"""
if not self.started:
await self.start_services()

ctx = ServerContext(
f"{self.name}[{name or protocol_class.__name__}]",
f"{self.name}[{name or 'WebSocket'}]",
self.connection_factory,
list(self.services.values()),
protocol_class
)
await ctx.listen(*address, proxy=proxy)
await ctx.listen(*address, path=path)

self.contexts.add(ctx)

Expand Down
25 changes: 9 additions & 16 deletions server/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,22 +44,15 @@ def __init__(self):
Change default values here.
"""
self.CONFIGURATION_REFRESH_TIME = 300
self.LISTEN = [
{
"ADDRESS": "",
"PORT": 8001,
"NAME": None,
"PROTOCOL": "QDataStreamProtocol",
"PROXY": False,
},
{
"ADDRESS": "",
"PORT": 8002,
"NAME": None,
"PROTOCOL": "SimpleJsonProtocol",
"PROXY": False
}
]
self.WS_HOST = ""
self.WS_PORT = 8003
self.WS_PATH = "/"
# Name of an HTTP header set by a trusted reverse proxy that contains
# the real client IP. Default "X-Real-IP" matches what Cloudflare /
# Traefik set. Set to "" to always use the direct TCP peer address
# when the server is exposed to untrusted clients (these headers are
# easily spoofed otherwise).
self.WS_FORWARDED_IP_HEADER = "X-Real-IP"
self.LOG_LEVEL = "DEBUG"
# Whether or not to use uvloop as a drop-in replacement for asyncio's
# default event loop
Expand Down
4 changes: 3 additions & 1 deletion server/protocol/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,14 @@
from .protocol import DisconnectedError, Protocol
from .qdatastream import QDataStreamProtocol
from .simple_json import SimpleJsonProtocol
from .websocket import WebSocketProtocol

__all__ = (
"DisconnectedError",
"GpgNetClientProtocol",
"GpgNetServerProtocol",
"Protocol",
"QDataStreamProtocol",
"SimpleJsonProtocol"
"SimpleJsonProtocol",
"WebSocketProtocol",
)
Loading
Loading