Skip to content

Commit 9263c8e

Browse files
committed
Allow an application to connect to websocket multiple times.
1 parent 45174ad commit 9263c8e

File tree

2 files changed

+30
-18
lines changed

2 files changed

+30
-18
lines changed

api/routes/members.py

+11-8
Original file line numberDiff line numberDiff line change
@@ -64,20 +64,23 @@ async def post_dpy_modlog(self, request: Request) -> Response:
6464
}
6565

6666
count = 0
67+
total = 0
6768
for subscriber in self.app.subscription_sockets[core.WebsocketSubscriptions.DPY_MOD_LOG]:
68-
websocket: WebSocket = self.app.sockets[subscriber]
69+
websockets: list[WebSocket] = list(self.app.sockets[subscriber].values())
6970

71+
total += len(websockets)
7072
payload['user_id'] = subscriber
7173

72-
try:
73-
await websocket.send_json(data=payload)
74-
except Exception as e:
75-
logger.debug(f'Failed to send payload to websocket "{subscriber}": {e}')
76-
else:
77-
count += 1
74+
for websocket in websockets:
75+
try:
76+
await websocket.send_json(data=payload)
77+
except Exception as e:
78+
logger.debug(f'Failed to send payload to a websocket for "{subscriber}": {e}')
79+
else:
80+
count += 1
7881

7982
to_send: dict[str, int] = {
80-
'subscribers': len(self.app.subscription_sockets[core.WebsocketSubscriptions.DPY_MOD_LOG]),
83+
'subscribers': total,
8184
'successful': count
8285
}
8386
return JSONResponse(to_send, status_code=200)

api/server.py

+19-10
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2121
SOFTWARE.
2222
"""
23+
import secrets
2324
from typing import Any
2425

2526
import aiohttp
@@ -50,7 +51,7 @@ def __init__(self, *, session: aiohttp.ClientSession, database: core.Database) -
5051
Middleware(AuthenticationMiddleware, backend=AuthBackend(self)),
5152
]
5253

53-
self.sockets: dict[int, WebSocket] = {}
54+
self.sockets: dict[int, dict[str, WebSocket]] = {}
5455
self.subscription_sockets: dict[str, set[int]] = {
5556
core.WebsocketSubscriptions.DPY_MOD_LOG: set()
5657
}
@@ -71,7 +72,12 @@ async def websocket_connector(self, websocket: WebSocket) -> None:
7172
uid: int | None = core.id_from_token(token)
7273

7374
assert uid
74-
self.sockets[uid] = websocket
75+
76+
hash_ = secrets.token_urlsafe(8)
77+
try:
78+
self.sockets[uid][hash_] = websocket
79+
except KeyError:
80+
self.sockets[uid] = {hash_: websocket}
7581

7682
# Filter out bad subscriptions...
7783
valid: list[str] = list(self.subscription_sockets.keys())
@@ -116,12 +122,8 @@ async def websocket_connector(self, websocket: WebSocket) -> None:
116122
}
117123
await websocket.send_json(data=response)
118124

119-
# Remove the websocket and it's subscriptions...
120-
del self.sockets[uid]
121-
122-
subscribed: list[str] = [sub for sub in self.subscription_sockets if uid in self.subscription_sockets[sub]]
123-
for sub in subscribed:
124-
self.subscription_sockets[sub].remove(uid)
125+
# Remove the websocket...
126+
del self.sockets[uid][hash_]
125127

126128
def websocket_subscribe(self, *, uid: int, message: dict[str, Any]) -> dict[str, Any]:
127129
subs: list[str] = message.get('subscriptions', [])
@@ -151,17 +153,24 @@ def websocket_unsubscribe(self, *, uid: int, message: dict[str, Any]) -> dict[st
151153
# Filter out bad subscriptions...
152154
valid: list[str] = list(self.subscription_sockets.keys())
153155
subscriptions: list[str] = [sub for sub in subs if sub in valid]
156+
removed: list[str] = []
154157

155158
for sub in subscriptions:
156-
self.subscription_sockets[sub].remove(uid)
159+
160+
try:
161+
self.subscription_sockets[sub].remove(uid)
162+
except KeyError:
163+
pass
164+
else:
165+
removed.append(sub)
157166

158167
subscribed: list[str] = [sub for sub in self.subscription_sockets if uid in self.subscription_sockets[sub]]
159168

160169
data: dict[str, Any] = {
161170
'op': core.WebsocketOPCodes.NOTIFICATION,
162171
'type': core.WebsocketNotificationTypes.SUBSCRIPTION_REMOVED,
163172
'user_id': uid,
164-
'removed': subscriptions,
173+
'removed': removed,
165174
'subscriptions': subscribed
166175
}
167176

0 commit comments

Comments
 (0)