@@ -90,6 +90,46 @@ application layer.
90
90
Read this `blog post <https://making.close.com/posts/reliable-websockets/ >`_ for
91
91
a complete walk-through of this issue.
92
92
93
+ Application-level keepalive
94
+ ---------------------------
95
+
96
+ Some servers require clients to send a keepalive message with a specific content
97
+ at regular intervals. Usually they expect Text _ frames rather than Ping _ frames,
98
+ meaning that you must send them with :attr: `~asyncio.connection.Connection.send `
99
+ rather than :attr: `~asyncio.connection.Connection.ping `.
100
+
101
+ .. _Text : https://www.rfc-editor.org/rfc/rfc6455.html#section-5.6
102
+
103
+ In websockets, such keepalive mechanisms are considered as application-level
104
+ because they rely on data frames. That's unlike the protocol-level keepalive
105
+ based on control frames. Therefore, it's your responsibility to implement the
106
+ required behavior.
107
+
108
+ You can run a task in the background to send keepalive messages:
109
+
110
+ .. code-block :: python
111
+
112
+ import itertools
113
+ import json
114
+
115
+ from websockets import ConnectionClosed
116
+
117
+ async def keepalive (websocket , ping_interval = 30 ):
118
+ for ping in itertools.count():
119
+ await asyncio.sleep(ping_interval)
120
+ try :
121
+ await websocket.send(json.dumps({" ping" : ping}))
122
+ except ConnectionClosed:
123
+ break
124
+
125
+ async def main ():
126
+ async with connect(... ) as websocket:
127
+ keepalive_task = asyncio.create_task(keepalive(websocket))
128
+ try :
129
+ ... # your application logic goes here
130
+ finally :
131
+ keepalive_task.cancel()
132
+
93
133
Latency issues
94
134
--------------
95
135
0 commit comments