Skip to content

Commit 41d9506

Browse files
➕ Add heartbeat handling of reply.
1 parent 2fbe10e commit 41d9506

File tree

4 files changed

+40
-3
lines changed

4 files changed

+40
-3
lines changed

plover_websocket_server/websocket/server.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,11 @@ async def websocket_handler(self, request: Request) -> WebSocketResponse:
120120
try:
121121
async for message in socket:
122122
if message.type == WSMsgType.TEXT:
123+
# Handle unencrypted heartbeat first
124+
if message.data == "ping":
125+
await socket.send_str("pong")
126+
continue
127+
123128
try:
124129
log.debug("Decrypting message...")
125130
decrypted: dict = mail_box.unbox(message.data)

pyproject.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@ include-package-data = false
4949
[project.optional-dependencies]
5050
test = [
5151
"pytest",
52-
"PyQt5"
52+
"PyQt5",
53+
"PySide6"
5354
]
5455

5556
dev = [

tests/client_example.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,13 @@ async def send_websocket_message(self, message) -> None:
181181
"""
182182
await self.socket.send_str(self.encrypt(message))
183183

184+
async def ping(self) -> None:
185+
"""
186+
Sends a raw 'ping' message to the server for heartbeat testing.
187+
188+
"""
189+
await self.socket.send_str("ping")
190+
184191
async def connect_to_websocket(self, message) -> None:
185192
"""
186193
Connects to the server using the WebSocket protocol.
@@ -195,12 +202,21 @@ async def connect_to_websocket(self, message) -> None:
195202
url,
196203
params=self._get_encryption_params(message),
197204
headers=self.headers,
198-
ssl=self.ssl_context,
205+
ssl= False if self.ssl_context is None else True,
199206
)
200207

201208
async def receive_json(self):
202209
return await self.socket.receive_json()
203210

211+
async def receive_raw(self):
212+
"""
213+
Receives a raw message from the websocket.
214+
215+
Returns:
216+
any: The raw data from the message.
217+
"""
218+
return (await self.socket.receive()).data
219+
204220
async def disconnect(self) -> None:
205221
"""
206222
Disconnects the client from the server by closing the session.

tests/test_server.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,21 @@ async def websocket(client: Client):
2525
assert reply == message
2626

2727

28+
async def ping_pong(client: Client):
29+
"""
30+
Callback function for testing websocket heartbeat (ping-pong).
31+
32+
Args:
33+
client (Client): The client object representing the websocket connection.
34+
35+
Returns:
36+
None
37+
"""
38+
await client.connect_to_websocket({"message": "ping-pong test"})
39+
await client.ping()
40+
reply = await client.receive_raw()
41+
assert reply == "pong"
42+
2843
async def http(client: Client):
2944
"""
3045
This function is the callback for HTTP requests.
@@ -38,7 +53,7 @@ async def http(client: Client):
3853
pass
3954

4055

41-
@mark.parametrize("callback", [http, websocket])
56+
@mark.parametrize("callback", [http, websocket, ping_pong])
4257
def test_server(callback: Awaitable) -> None:
4358
"""
4459
Test the server functionality.

0 commit comments

Comments
 (0)