socket-netty 0.3.0__tar.gz → 0.3.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {socket_netty-0.3.0 → socket_netty-0.3.2}/PKG-INFO +43 -49
- {socket_netty-0.3.0 → socket_netty-0.3.2}/README.md +42 -48
- {socket_netty-0.3.0 → socket_netty-0.3.2}/examples/01_echo_client.py +3 -3
- {socket_netty-0.3.0 → socket_netty-0.3.2}/examples/01_echo_server.py +2 -2
- {socket_netty-0.3.0 → socket_netty-0.3.2}/examples/02_game_protocol_client.py +3 -3
- {socket_netty-0.3.0 → socket_netty-0.3.2}/examples/02_game_protocol_server.py +2 -2
- {socket_netty-0.3.0 → socket_netty-0.3.2}/pyproject.toml +2 -2
- {socket_netty-0.3.0/pynetty → socket_netty-0.3.2/socket_netty}/__init__.py +8 -8
- socket_netty-0.3.2/socket_netty/bootstrap/__init__.py +3 -0
- {socket_netty-0.3.0/pynetty → socket_netty-0.3.2/socket_netty}/bootstrap/bootstrap.py +6 -6
- {socket_netty-0.3.0/pynetty → socket_netty-0.3.2/socket_netty}/buffer/__init__.py +2 -2
- {socket_netty-0.3.0/pynetty → socket_netty-0.3.2/socket_netty}/buffer/allocator.py +1 -1
- {socket_netty-0.3.0/pynetty → socket_netty-0.3.2/socket_netty}/buffer/bytebuf.py +1 -1
- socket_netty-0.3.2/socket_netty/channel/__init__.py +24 -0
- {socket_netty-0.3.0/pynetty → socket_netty-0.3.2/socket_netty}/channel/channel.py +3 -3
- {socket_netty-0.3.0/pynetty → socket_netty-0.3.2/socket_netty}/channel/channel_pipeline.py +4 -4
- {socket_netty-0.3.0/pynetty → socket_netty-0.3.2/socket_netty}/channel/datagram_channel.py +2 -2
- {socket_netty-0.3.0/pynetty → socket_netty-0.3.2/socket_netty}/channel/event_loop.py +2 -2
- {socket_netty-0.3.0/pynetty → socket_netty-0.3.2/socket_netty}/channel/protocol_adapter.py +2 -2
- {socket_netty-0.3.0/pynetty → socket_netty-0.3.2/socket_netty}/exceptions.py +1 -1
- {socket_netty-0.3.0/pynetty → socket_netty-0.3.2/socket_netty}/handler/__init__.py +6 -6
- {socket_netty-0.3.0/pynetty → socket_netty-0.3.2/socket_netty}/handler/channel_handler.py +1 -1
- {socket_netty-0.3.0/pynetty → socket_netty-0.3.2/socket_netty}/handler/channel_handler_context.py +5 -5
- {socket_netty-0.3.0/pynetty → socket_netty-0.3.2/socket_netty}/handler/codec.py +4 -4
- {socket_netty-0.3.0/pynetty → socket_netty-0.3.2/socket_netty}/handler/protolib_codec.py +7 -7
- {socket_netty-0.3.0/pynetty → socket_netty-0.3.2/socket_netty}/handler/timeout.py +4 -4
- {socket_netty-0.3.0 → socket_netty-0.3.2}/socket_netty.egg-info/PKG-INFO +43 -49
- socket_netty-0.3.2/socket_netty.egg-info/SOURCES.txt +44 -0
- socket_netty-0.3.2/socket_netty.egg-info/top_level.txt +1 -0
- {socket_netty-0.3.0 → socket_netty-0.3.2}/tests/test_bytebuf.py +5 -5
- {socket_netty-0.3.0 → socket_netty-0.3.2}/tests/test_codec.py +3 -3
- {socket_netty-0.3.0 → socket_netty-0.3.2}/tests/test_concurrency.py +3 -3
- {socket_netty-0.3.0 → socket_netty-0.3.2}/tests/test_core_extras.py +3 -3
- {socket_netty-0.3.0 → socket_netty-0.3.2}/tests/test_echo.py +5 -5
- {socket_netty-0.3.0 → socket_netty-0.3.2}/tests/test_flow_and_allocator.py +5 -5
- {socket_netty-0.3.0 → socket_netty-0.3.2}/tests/test_network_extras.py +3 -3
- {socket_netty-0.3.0 → socket_netty-0.3.2}/tests/test_pipeline.py +5 -5
- {socket_netty-0.3.0 → socket_netty-0.3.2}/tests/test_tls.py +3 -3
- socket_netty-0.3.0/pynetty/bootstrap/__init__.py +0 -3
- socket_netty-0.3.0/pynetty/channel/__init__.py +0 -24
- socket_netty-0.3.0/socket_netty.egg-info/SOURCES.txt +0 -44
- socket_netty-0.3.0/socket_netty.egg-info/top_level.txt +0 -1
- {socket_netty-0.3.0 → socket_netty-0.3.2}/MANIFEST.in +0 -0
- {socket_netty-0.3.0 → socket_netty-0.3.2}/setup.cfg +0 -0
- {socket_netty-0.3.0/pynetty → socket_netty-0.3.2/socket_netty}/channel/channel_future.py +0 -0
- {socket_netty-0.3.0/pynetty → socket_netty-0.3.2/socket_netty}/channel/channel_option.py +0 -0
- {socket_netty-0.3.0/pynetty → socket_netty-0.3.2/socket_netty}/channel/flow_control.py +0 -0
- {socket_netty-0.3.0/pynetty → socket_netty-0.3.2/socket_netty}/handler/ssl_context.py +0 -0
- {socket_netty-0.3.0 → socket_netty-0.3.2}/socket_netty.egg-info/dependency_links.txt +0 -0
- {socket_netty-0.3.0 → socket_netty-0.3.2}/socket_netty.egg-info/requires.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: socket-netty
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.2
|
|
4
4
|
Summary: Asynchronous networking library for Python, inspired by Netty
|
|
5
5
|
Author: Button
|
|
6
6
|
Keywords: networking,asyncio,netty,tcp,udp,game-server,protocol
|
|
@@ -18,7 +18,7 @@ Requires-Python: >=3.9
|
|
|
18
18
|
Description-Content-Type: text/markdown
|
|
19
19
|
Requires-Dist: protolib>=0.4.3
|
|
20
20
|
|
|
21
|
-
#
|
|
21
|
+
# socket-netty
|
|
22
22
|
|
|
23
23
|
Asynchronous networking library for Python, closely inspired by
|
|
24
24
|
[Netty](https://netty.io) (Java). Built on top of `asyncio`, with no
|
|
@@ -26,33 +26,30 @@ external dependencies.
|
|
|
26
26
|
|
|
27
27
|
## Coverage relative to Netty
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
└── Declarative packet codec ✅ (ProtolibCodec, via the protolib
|
|
54
|
-
dependency)
|
|
55
|
-
```
|
|
29
|
+
| Netty | Python (socket-netty) | Notes |
|
|
30
|
+
|---|---|---|
|
|
31
|
+
| Bootstrap | Yes | |
|
|
32
|
+
| ServerBootstrap | Yes | |
|
|
33
|
+
| Channel | Yes | TCP |
|
|
34
|
+
| ChannelPipeline | Yes | |
|
|
35
|
+
| ChannelHandler | Yes | inbound + outbound |
|
|
36
|
+
| ChannelHandlerContext | Yes | |
|
|
37
|
+
| EventLoop | Yes | |
|
|
38
|
+
| EventLoopGroup | Yes | |
|
|
39
|
+
| ChannelFuture | Yes | + ChannelPromise |
|
|
40
|
+
| ByteBuf | Yes | |
|
|
41
|
+
| Allocator | Yes | Unpooled + Pooled |
|
|
42
|
+
| TCP | Yes | |
|
|
43
|
+
| UDP | Yes | DatagramChannel |
|
|
44
|
+
| Socket options | Yes | ChannelOption |
|
|
45
|
+
| Backpressure | Yes | WriteBufferWaterMark |
|
|
46
|
+
| Concurrency | Yes | ChannelExecutor |
|
|
47
|
+
| TLS/SSL | Yes | SslContextBuilder |
|
|
48
|
+
| Encoders / Decoders | Yes | length-based framing |
|
|
49
|
+
| Idle handlers | Yes | IdleStateHandler |
|
|
50
|
+
| Timeouts | Yes | Read/WriteTimeoutHandler |
|
|
51
|
+
| Exception handling | Yes | `exception_caught` via the pipeline, `io.netty.*`-style exception classes |
|
|
52
|
+
| Declarative packet codec | Yes | ProtolibCodec, via the `protolib` dependency |
|
|
56
53
|
|
|
57
54
|
## Installation
|
|
58
55
|
|
|
@@ -60,16 +57,13 @@ Netty Py 🐍
|
|
|
60
57
|
pip install socket-netty
|
|
61
58
|
```
|
|
62
59
|
|
|
63
|
-
(The PyPI distribution is named `socket-netty`, but the importable
|
|
64
|
-
package is still `pynetty` — your code stays `import pynetty`.)
|
|
65
|
-
|
|
66
60
|
Or, for local development from a clone of this repo:
|
|
67
61
|
|
|
68
62
|
```bash
|
|
69
63
|
pip install -e .
|
|
70
64
|
```
|
|
71
65
|
|
|
72
|
-
`
|
|
66
|
+
`socket_netty` declares [`protolib`](https://pypi.org/project/protolib/) as
|
|
73
67
|
an install dependency, so either install method pulls it in
|
|
74
68
|
automatically — you don't need a separate install step to use
|
|
75
69
|
`ProtolibCodec` below.
|
|
@@ -77,7 +71,7 @@ automatically — you don't need a separate install step to use
|
|
|
77
71
|
## Structure
|
|
78
72
|
|
|
79
73
|
```
|
|
80
|
-
|
|
74
|
+
socket_netty/
|
|
81
75
|
exceptions.py -> Netty-style exception hierarchy (DecoderException,
|
|
82
76
|
EncoderException, CorruptedFrameException, etc.)
|
|
83
77
|
buffer/ -> ByteBuf, ByteBufAllocator (Unpooled/Pooled)
|
|
@@ -93,7 +87,7 @@ pynetty/
|
|
|
93
87
|
|
|
94
88
|
```python
|
|
95
89
|
import asyncio
|
|
96
|
-
from
|
|
90
|
+
from socket_netty import ServerBootstrap, ChannelInboundHandler
|
|
97
91
|
|
|
98
92
|
class EchoHandler(ChannelInboundHandler):
|
|
99
93
|
async def channel_active(self, ctx):
|
|
@@ -118,13 +112,13 @@ asyncio.run(main())
|
|
|
118
112
|
|
|
119
113
|
## Exceptions
|
|
120
114
|
|
|
121
|
-
|
|
115
|
+
socket_netty raises the same exception hierarchy Netty does, under
|
|
122
116
|
`io.netty.*`. Every exception's `str()` is prefixed with its
|
|
123
117
|
fully-qualified Java-style path, so logs and `exception_caught` output
|
|
124
118
|
look exactly like a real Netty stack:
|
|
125
119
|
|
|
126
120
|
```python
|
|
127
|
-
from
|
|
121
|
+
from socket_netty import DecoderException
|
|
128
122
|
|
|
129
123
|
async def exception_caught(self, ctx, exc):
|
|
130
124
|
print(exc)
|
|
@@ -155,7 +149,7 @@ raw internal error escape a codec unwrapped.
|
|
|
155
149
|
## Socket options
|
|
156
150
|
|
|
157
151
|
```python
|
|
158
|
-
from
|
|
152
|
+
from socket_netty import ServerBootstrap, ChannelOption
|
|
159
153
|
|
|
160
154
|
server = (
|
|
161
155
|
ServerBootstrap()
|
|
@@ -170,7 +164,7 @@ await server.bind("0.0.0.0", 9000)
|
|
|
170
164
|
## TLS/SSL
|
|
171
165
|
|
|
172
166
|
```python
|
|
173
|
-
from
|
|
167
|
+
from socket_netty import ServerBootstrap, Bootstrap, SslContextBuilder
|
|
174
168
|
|
|
175
169
|
# Server
|
|
176
170
|
server_ctx = SslContextBuilder.for_server("cert.pem", "key.pem").build()
|
|
@@ -185,7 +179,7 @@ channel = await Bootstrap().handler(init_client).ssl(client_ctx).connect("myserv
|
|
|
185
179
|
## UDP
|
|
186
180
|
|
|
187
181
|
```python
|
|
188
|
-
from
|
|
182
|
+
from socket_netty import DatagramBootstrap, ChannelInboundHandler
|
|
189
183
|
|
|
190
184
|
class UdpHandler(ChannelInboundHandler):
|
|
191
185
|
async def channel_read(self, ctx, msg):
|
|
@@ -200,7 +194,7 @@ channel = await DatagramBootstrap().handler(
|
|
|
200
194
|
## Idle / Timeouts
|
|
201
195
|
|
|
202
196
|
```python
|
|
203
|
-
from
|
|
197
|
+
from socket_netty import IdleStateHandler, ReadTimeoutHandler
|
|
204
198
|
|
|
205
199
|
async def on_idle(ctx, event):
|
|
206
200
|
print("Idle channel:", event.state)
|
|
@@ -217,7 +211,7 @@ def init_channel(channel):
|
|
|
217
211
|
## EventLoopGroup (real multi-threaded concurrency)
|
|
218
212
|
|
|
219
213
|
```python
|
|
220
|
-
from
|
|
214
|
+
from socket_netty import EventLoopGroup
|
|
221
215
|
|
|
222
216
|
worker_group = EventLoopGroup(num_threads=4)
|
|
223
217
|
worker_group.start()
|
|
@@ -230,7 +224,7 @@ result = future.result(timeout=5) # blocking, from any thread
|
|
|
230
224
|
## ChannelFuture / ChannelPromise
|
|
231
225
|
|
|
232
226
|
```python
|
|
233
|
-
from
|
|
227
|
+
from socket_netty import ChannelFuture
|
|
234
228
|
|
|
235
229
|
future = channel.new_future()
|
|
236
230
|
future.add_listener(lambda f: print("Finished:", f.is_success()))
|
|
@@ -242,7 +236,7 @@ result = await future
|
|
|
242
236
|
## Backpressure (WriteBufferWaterMark)
|
|
243
237
|
|
|
244
238
|
```python
|
|
245
|
-
from
|
|
239
|
+
from socket_netty import ServerBootstrap, WriteBufferWaterMark
|
|
246
240
|
|
|
247
241
|
server = (
|
|
248
242
|
ServerBootstrap()
|
|
@@ -263,7 +257,7 @@ order, even across `await` points (avoids race conditions on shared
|
|
|
263
257
|
handler state):
|
|
264
258
|
|
|
265
259
|
```python
|
|
266
|
-
from
|
|
260
|
+
from socket_netty import ChannelExecutor
|
|
267
261
|
|
|
268
262
|
executor = ChannelExecutor()
|
|
269
263
|
executor.start()
|
|
@@ -275,7 +269,7 @@ async def channel_read(self, ctx, msg):
|
|
|
275
269
|
## Allocator (buffer pool)
|
|
276
270
|
|
|
277
271
|
```python
|
|
278
|
-
from
|
|
272
|
+
from socket_netty import PooledByteBufAllocator
|
|
279
273
|
|
|
280
274
|
allocator = PooledByteBufAllocator()
|
|
281
275
|
buf = allocator.buffer(256)
|
|
@@ -289,7 +283,7 @@ allocator.release(buf) # goes back to the pool, ready to be reused
|
|
|
289
283
|
Very common in game protocols (Minecraft, Free Fire, etc.):
|
|
290
284
|
|
|
291
285
|
```python
|
|
292
|
-
from
|
|
286
|
+
from socket_netty import LengthFieldBasedFrameDecoder, LengthFieldPrepender
|
|
293
287
|
|
|
294
288
|
def init_channel(channel):
|
|
295
289
|
channel.pipeline.add_last("frame_decoder", LengthFieldBasedFrameDecoder(4))
|
|
@@ -313,7 +307,7 @@ out.
|
|
|
313
307
|
`ProtolibCodec` has two framing modes, controlled by `framed`:
|
|
314
308
|
|
|
315
309
|
```python
|
|
316
|
-
from
|
|
310
|
+
from socket_netty import ServerBootstrap, ChannelInboundHandler, ProtolibCodec
|
|
317
311
|
|
|
318
312
|
# framed=True (default): the codec frames the stream itself via
|
|
319
313
|
# protolib's own PacketFramer (varint length-prefix, Minecraft-style).
|
|
@@ -354,7 +348,7 @@ same as the rest of the codecs in this library.
|
|
|
354
348
|
## ByteBuf
|
|
355
349
|
|
|
356
350
|
```python
|
|
357
|
-
from
|
|
351
|
+
from socket_netty import ByteBuf
|
|
358
352
|
|
|
359
353
|
buf = ByteBuf()
|
|
360
354
|
buf.write_varint(1000)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#
|
|
1
|
+
# socket-netty
|
|
2
2
|
|
|
3
3
|
Asynchronous networking library for Python, closely inspired by
|
|
4
4
|
[Netty](https://netty.io) (Java). Built on top of `asyncio`, with no
|
|
@@ -6,33 +6,30 @@ external dependencies.
|
|
|
6
6
|
|
|
7
7
|
## Coverage relative to Netty
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
└── Declarative packet codec ✅ (ProtolibCodec, via the protolib
|
|
34
|
-
dependency)
|
|
35
|
-
```
|
|
9
|
+
| Netty | Python (socket-netty) | Notes |
|
|
10
|
+
|---|---|---|
|
|
11
|
+
| Bootstrap | Yes | |
|
|
12
|
+
| ServerBootstrap | Yes | |
|
|
13
|
+
| Channel | Yes | TCP |
|
|
14
|
+
| ChannelPipeline | Yes | |
|
|
15
|
+
| ChannelHandler | Yes | inbound + outbound |
|
|
16
|
+
| ChannelHandlerContext | Yes | |
|
|
17
|
+
| EventLoop | Yes | |
|
|
18
|
+
| EventLoopGroup | Yes | |
|
|
19
|
+
| ChannelFuture | Yes | + ChannelPromise |
|
|
20
|
+
| ByteBuf | Yes | |
|
|
21
|
+
| Allocator | Yes | Unpooled + Pooled |
|
|
22
|
+
| TCP | Yes | |
|
|
23
|
+
| UDP | Yes | DatagramChannel |
|
|
24
|
+
| Socket options | Yes | ChannelOption |
|
|
25
|
+
| Backpressure | Yes | WriteBufferWaterMark |
|
|
26
|
+
| Concurrency | Yes | ChannelExecutor |
|
|
27
|
+
| TLS/SSL | Yes | SslContextBuilder |
|
|
28
|
+
| Encoders / Decoders | Yes | length-based framing |
|
|
29
|
+
| Idle handlers | Yes | IdleStateHandler |
|
|
30
|
+
| Timeouts | Yes | Read/WriteTimeoutHandler |
|
|
31
|
+
| Exception handling | Yes | `exception_caught` via the pipeline, `io.netty.*`-style exception classes |
|
|
32
|
+
| Declarative packet codec | Yes | ProtolibCodec, via the `protolib` dependency |
|
|
36
33
|
|
|
37
34
|
## Installation
|
|
38
35
|
|
|
@@ -40,16 +37,13 @@ Netty Py 🐍
|
|
|
40
37
|
pip install socket-netty
|
|
41
38
|
```
|
|
42
39
|
|
|
43
|
-
(The PyPI distribution is named `socket-netty`, but the importable
|
|
44
|
-
package is still `pynetty` — your code stays `import pynetty`.)
|
|
45
|
-
|
|
46
40
|
Or, for local development from a clone of this repo:
|
|
47
41
|
|
|
48
42
|
```bash
|
|
49
43
|
pip install -e .
|
|
50
44
|
```
|
|
51
45
|
|
|
52
|
-
`
|
|
46
|
+
`socket_netty` declares [`protolib`](https://pypi.org/project/protolib/) as
|
|
53
47
|
an install dependency, so either install method pulls it in
|
|
54
48
|
automatically — you don't need a separate install step to use
|
|
55
49
|
`ProtolibCodec` below.
|
|
@@ -57,7 +51,7 @@ automatically — you don't need a separate install step to use
|
|
|
57
51
|
## Structure
|
|
58
52
|
|
|
59
53
|
```
|
|
60
|
-
|
|
54
|
+
socket_netty/
|
|
61
55
|
exceptions.py -> Netty-style exception hierarchy (DecoderException,
|
|
62
56
|
EncoderException, CorruptedFrameException, etc.)
|
|
63
57
|
buffer/ -> ByteBuf, ByteBufAllocator (Unpooled/Pooled)
|
|
@@ -73,7 +67,7 @@ pynetty/
|
|
|
73
67
|
|
|
74
68
|
```python
|
|
75
69
|
import asyncio
|
|
76
|
-
from
|
|
70
|
+
from socket_netty import ServerBootstrap, ChannelInboundHandler
|
|
77
71
|
|
|
78
72
|
class EchoHandler(ChannelInboundHandler):
|
|
79
73
|
async def channel_active(self, ctx):
|
|
@@ -98,13 +92,13 @@ asyncio.run(main())
|
|
|
98
92
|
|
|
99
93
|
## Exceptions
|
|
100
94
|
|
|
101
|
-
|
|
95
|
+
socket_netty raises the same exception hierarchy Netty does, under
|
|
102
96
|
`io.netty.*`. Every exception's `str()` is prefixed with its
|
|
103
97
|
fully-qualified Java-style path, so logs and `exception_caught` output
|
|
104
98
|
look exactly like a real Netty stack:
|
|
105
99
|
|
|
106
100
|
```python
|
|
107
|
-
from
|
|
101
|
+
from socket_netty import DecoderException
|
|
108
102
|
|
|
109
103
|
async def exception_caught(self, ctx, exc):
|
|
110
104
|
print(exc)
|
|
@@ -135,7 +129,7 @@ raw internal error escape a codec unwrapped.
|
|
|
135
129
|
## Socket options
|
|
136
130
|
|
|
137
131
|
```python
|
|
138
|
-
from
|
|
132
|
+
from socket_netty import ServerBootstrap, ChannelOption
|
|
139
133
|
|
|
140
134
|
server = (
|
|
141
135
|
ServerBootstrap()
|
|
@@ -150,7 +144,7 @@ await server.bind("0.0.0.0", 9000)
|
|
|
150
144
|
## TLS/SSL
|
|
151
145
|
|
|
152
146
|
```python
|
|
153
|
-
from
|
|
147
|
+
from socket_netty import ServerBootstrap, Bootstrap, SslContextBuilder
|
|
154
148
|
|
|
155
149
|
# Server
|
|
156
150
|
server_ctx = SslContextBuilder.for_server("cert.pem", "key.pem").build()
|
|
@@ -165,7 +159,7 @@ channel = await Bootstrap().handler(init_client).ssl(client_ctx).connect("myserv
|
|
|
165
159
|
## UDP
|
|
166
160
|
|
|
167
161
|
```python
|
|
168
|
-
from
|
|
162
|
+
from socket_netty import DatagramBootstrap, ChannelInboundHandler
|
|
169
163
|
|
|
170
164
|
class UdpHandler(ChannelInboundHandler):
|
|
171
165
|
async def channel_read(self, ctx, msg):
|
|
@@ -180,7 +174,7 @@ channel = await DatagramBootstrap().handler(
|
|
|
180
174
|
## Idle / Timeouts
|
|
181
175
|
|
|
182
176
|
```python
|
|
183
|
-
from
|
|
177
|
+
from socket_netty import IdleStateHandler, ReadTimeoutHandler
|
|
184
178
|
|
|
185
179
|
async def on_idle(ctx, event):
|
|
186
180
|
print("Idle channel:", event.state)
|
|
@@ -197,7 +191,7 @@ def init_channel(channel):
|
|
|
197
191
|
## EventLoopGroup (real multi-threaded concurrency)
|
|
198
192
|
|
|
199
193
|
```python
|
|
200
|
-
from
|
|
194
|
+
from socket_netty import EventLoopGroup
|
|
201
195
|
|
|
202
196
|
worker_group = EventLoopGroup(num_threads=4)
|
|
203
197
|
worker_group.start()
|
|
@@ -210,7 +204,7 @@ result = future.result(timeout=5) # blocking, from any thread
|
|
|
210
204
|
## ChannelFuture / ChannelPromise
|
|
211
205
|
|
|
212
206
|
```python
|
|
213
|
-
from
|
|
207
|
+
from socket_netty import ChannelFuture
|
|
214
208
|
|
|
215
209
|
future = channel.new_future()
|
|
216
210
|
future.add_listener(lambda f: print("Finished:", f.is_success()))
|
|
@@ -222,7 +216,7 @@ result = await future
|
|
|
222
216
|
## Backpressure (WriteBufferWaterMark)
|
|
223
217
|
|
|
224
218
|
```python
|
|
225
|
-
from
|
|
219
|
+
from socket_netty import ServerBootstrap, WriteBufferWaterMark
|
|
226
220
|
|
|
227
221
|
server = (
|
|
228
222
|
ServerBootstrap()
|
|
@@ -243,7 +237,7 @@ order, even across `await` points (avoids race conditions on shared
|
|
|
243
237
|
handler state):
|
|
244
238
|
|
|
245
239
|
```python
|
|
246
|
-
from
|
|
240
|
+
from socket_netty import ChannelExecutor
|
|
247
241
|
|
|
248
242
|
executor = ChannelExecutor()
|
|
249
243
|
executor.start()
|
|
@@ -255,7 +249,7 @@ async def channel_read(self, ctx, msg):
|
|
|
255
249
|
## Allocator (buffer pool)
|
|
256
250
|
|
|
257
251
|
```python
|
|
258
|
-
from
|
|
252
|
+
from socket_netty import PooledByteBufAllocator
|
|
259
253
|
|
|
260
254
|
allocator = PooledByteBufAllocator()
|
|
261
255
|
buf = allocator.buffer(256)
|
|
@@ -269,7 +263,7 @@ allocator.release(buf) # goes back to the pool, ready to be reused
|
|
|
269
263
|
Very common in game protocols (Minecraft, Free Fire, etc.):
|
|
270
264
|
|
|
271
265
|
```python
|
|
272
|
-
from
|
|
266
|
+
from socket_netty import LengthFieldBasedFrameDecoder, LengthFieldPrepender
|
|
273
267
|
|
|
274
268
|
def init_channel(channel):
|
|
275
269
|
channel.pipeline.add_last("frame_decoder", LengthFieldBasedFrameDecoder(4))
|
|
@@ -293,7 +287,7 @@ out.
|
|
|
293
287
|
`ProtolibCodec` has two framing modes, controlled by `framed`:
|
|
294
288
|
|
|
295
289
|
```python
|
|
296
|
-
from
|
|
290
|
+
from socket_netty import ServerBootstrap, ChannelInboundHandler, ProtolibCodec
|
|
297
291
|
|
|
298
292
|
# framed=True (default): the codec frames the stream itself via
|
|
299
293
|
# protolib's own PacketFramer (varint length-prefix, Minecraft-style).
|
|
@@ -334,7 +328,7 @@ same as the rest of the codecs in this library.
|
|
|
334
328
|
## ByteBuf
|
|
335
329
|
|
|
336
330
|
```python
|
|
337
|
-
from
|
|
331
|
+
from socket_netty import ByteBuf
|
|
338
332
|
|
|
339
333
|
buf = ByteBuf()
|
|
340
334
|
buf.write_varint(1000)
|
|
@@ -7,11 +7,11 @@ Uso:
|
|
|
7
7
|
"""
|
|
8
8
|
|
|
9
9
|
import sys
|
|
10
|
-
sys.path.insert(0, "/home/claude/
|
|
10
|
+
sys.path.insert(0, "/home/claude/socket_netty")
|
|
11
11
|
|
|
12
12
|
import asyncio
|
|
13
13
|
|
|
14
|
-
from
|
|
14
|
+
from socket_netty import Bootstrap, ChannelInboundHandler
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
class ClientHandler(ChannelInboundHandler):
|
|
@@ -35,7 +35,7 @@ async def main():
|
|
|
35
35
|
channel = await Bootstrap().handler(init_channel).connect("127.0.0.1", 9000)
|
|
36
36
|
print(f"[client] conectado a {channel.remote_address()}")
|
|
37
37
|
|
|
38
|
-
mensajes = [b"hola", b"como estas", b"
|
|
38
|
+
mensajes = [b"hola", b"como estas", b"socket_netty rifa \xf0\x9f\x9b\xa0"]
|
|
39
39
|
for m in mensajes:
|
|
40
40
|
await channel.write(m)
|
|
41
41
|
respuesta = await asyncio.wait_for(handler.received.get(), timeout=5)
|
|
@@ -10,11 +10,11 @@ Uso:
|
|
|
10
10
|
"""
|
|
11
11
|
|
|
12
12
|
import sys
|
|
13
|
-
sys.path.insert(0, "/home/claude/
|
|
13
|
+
sys.path.insert(0, "/home/claude/socket_netty")
|
|
14
14
|
|
|
15
15
|
import asyncio
|
|
16
16
|
|
|
17
|
-
from
|
|
17
|
+
from socket_netty import ServerBootstrap, ChannelInboundHandler, ChannelOption
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
class EchoHandler(ChannelInboundHandler):
|
|
@@ -8,11 +8,11 @@ Uso:
|
|
|
8
8
|
"""
|
|
9
9
|
|
|
10
10
|
import sys
|
|
11
|
-
sys.path.insert(0, "/home/claude/
|
|
11
|
+
sys.path.insert(0, "/home/claude/socket_netty")
|
|
12
12
|
|
|
13
13
|
import asyncio
|
|
14
14
|
|
|
15
|
-
from
|
|
15
|
+
from socket_netty import (
|
|
16
16
|
Bootstrap,
|
|
17
17
|
ChannelInboundHandler,
|
|
18
18
|
ChannelOutboundHandler,
|
|
@@ -83,7 +83,7 @@ async def main():
|
|
|
83
83
|
|
|
84
84
|
# 3) Chat
|
|
85
85
|
chat_buf = ByteBuf()
|
|
86
|
-
chat_buf.write_string(f"hola desde {username}
|
|
86
|
+
chat_buf.write_string(f"hola desde {username}")
|
|
87
87
|
await channel.write((OP_CHAT, chat_buf.to_bytes()))
|
|
88
88
|
|
|
89
89
|
# escucha respuestas unos segundos antes de cerrar
|
|
@@ -18,11 +18,11 @@ Uso:
|
|
|
18
18
|
"""
|
|
19
19
|
|
|
20
20
|
import sys
|
|
21
|
-
sys.path.insert(0, "/home/claude/
|
|
21
|
+
sys.path.insert(0, "/home/claude/socket_netty")
|
|
22
22
|
|
|
23
23
|
import asyncio
|
|
24
24
|
|
|
25
|
-
from
|
|
25
|
+
from socket_netty import (
|
|
26
26
|
ServerBootstrap,
|
|
27
27
|
ChannelInboundHandler,
|
|
28
28
|
ChannelOutboundHandler,
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "socket-netty"
|
|
7
|
-
version = "0.3.
|
|
7
|
+
version = "0.3.2"
|
|
8
8
|
description = "Asynchronous networking library for Python, inspired by Netty"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.9"
|
|
@@ -29,4 +29,4 @@ dependencies = [
|
|
|
29
29
|
]
|
|
30
30
|
|
|
31
31
|
[tool.setuptools.packages.find]
|
|
32
|
-
include = ["
|
|
32
|
+
include = ["socket_netty", "socket_netty.*"]
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
"""
|
|
2
|
-
|
|
2
|
+
socket_netty: an event-driven asynchronous I/O library inspired by Netty
|
|
3
3
|
(Java), built on top of asyncio.
|
|
4
4
|
|
|
5
5
|
Typical usage (server):
|
|
6
6
|
|
|
7
|
-
from
|
|
7
|
+
from socket_netty import ServerBootstrap, ChannelInboundHandler
|
|
8
8
|
|
|
9
9
|
class EchoHandler(ChannelInboundHandler):
|
|
10
10
|
async def channel_read(self, ctx, msg):
|
|
@@ -18,7 +18,7 @@ Typical usage (server):
|
|
|
18
18
|
await server.serve_forever()
|
|
19
19
|
"""
|
|
20
20
|
|
|
21
|
-
from
|
|
21
|
+
from socket_netty.buffer import (
|
|
22
22
|
ByteBuf,
|
|
23
23
|
IndexOutOfBoundsError,
|
|
24
24
|
ByteBufAllocator,
|
|
@@ -27,7 +27,7 @@ from pynetty.buffer import (
|
|
|
27
27
|
DEFAULT_UNPOOLED,
|
|
28
28
|
DEFAULT_POOLED,
|
|
29
29
|
)
|
|
30
|
-
from
|
|
30
|
+
from socket_netty.channel import (
|
|
31
31
|
Channel,
|
|
32
32
|
ChannelPipeline,
|
|
33
33
|
DuplicateHandlerNameError,
|
|
@@ -43,7 +43,7 @@ from pynetty.channel import (
|
|
|
43
43
|
DatagramChannel,
|
|
44
44
|
DatagramBootstrap,
|
|
45
45
|
)
|
|
46
|
-
from
|
|
46
|
+
from socket_netty.handler import (
|
|
47
47
|
ChannelHandler,
|
|
48
48
|
ChannelInboundHandler,
|
|
49
49
|
ChannelOutboundHandler,
|
|
@@ -64,8 +64,8 @@ from pynetty.handler import (
|
|
|
64
64
|
WriteTimeoutHandler,
|
|
65
65
|
WriteTimeoutError,
|
|
66
66
|
)
|
|
67
|
-
from
|
|
68
|
-
from
|
|
67
|
+
from socket_netty.bootstrap import ServerBootstrap, Bootstrap
|
|
68
|
+
from socket_netty.exceptions import (
|
|
69
69
|
NettyException,
|
|
70
70
|
ChannelException,
|
|
71
71
|
CodecException,
|
|
@@ -76,7 +76,7 @@ from pynetty.exceptions import (
|
|
|
76
76
|
TimeoutException,
|
|
77
77
|
)
|
|
78
78
|
|
|
79
|
-
__version__ = "0.3.
|
|
79
|
+
__version__ = "0.3.2"
|
|
80
80
|
|
|
81
81
|
__all__ = [
|
|
82
82
|
# exceptions
|
|
@@ -12,12 +12,12 @@ import asyncio
|
|
|
12
12
|
import ssl as ssl_module
|
|
13
13
|
from typing import Any, Callable, Dict, Optional
|
|
14
14
|
|
|
15
|
-
from
|
|
16
|
-
from
|
|
17
|
-
from
|
|
18
|
-
from
|
|
19
|
-
from
|
|
20
|
-
from
|
|
15
|
+
from socket_netty.channel.channel import Channel
|
|
16
|
+
from socket_netty.channel.protocol_adapter import _ChannelProtocol
|
|
17
|
+
from socket_netty.channel.channel_option import ChannelOption, apply_socket_options
|
|
18
|
+
from socket_netty.channel.flow_control import WriteBufferWaterMark
|
|
19
|
+
from socket_netty.channel.event_loop import EventLoopGroup
|
|
20
|
+
from socket_netty.exceptions import ChannelException
|
|
21
21
|
|
|
22
22
|
|
|
23
23
|
ChannelInitializer = Callable[[Channel], "asyncio.Future | None"]
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
from
|
|
2
|
-
from
|
|
1
|
+
from socket_netty.buffer.bytebuf import ByteBuf, IndexOutOfBoundsError
|
|
2
|
+
from socket_netty.buffer.allocator import (
|
|
3
3
|
ByteBufAllocator,
|
|
4
4
|
UnpooledByteBufAllocator,
|
|
5
5
|
PooledByteBufAllocator,
|
|
@@ -11,7 +11,7 @@ from __future__ import annotations
|
|
|
11
11
|
import struct
|
|
12
12
|
from typing import Union
|
|
13
13
|
|
|
14
|
-
from
|
|
14
|
+
from socket_netty.exceptions import IndexOutOfBoundsError, CorruptedFrameException
|
|
15
15
|
|
|
16
16
|
__all__ = ["ByteBuf", "IndexOutOfBoundsError"]
|
|
17
17
|
|