flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics --exclude benchmark Excluding the benchmark directory (due to protobuf generated files) Also removing some Python2 specific code
95 lines
2.3 KiB
Python
Executable File
95 lines
2.3 KiB
Python
Executable File
#!/usr/bin/env python
|
|
|
|
from __future__ import print_function
|
|
|
|
import argparse
|
|
import capnp
|
|
|
|
import thread_capnp
|
|
import asyncio
|
|
import socket
|
|
import ssl
|
|
|
|
|
|
class ExampleImpl(thread_capnp.Example.Server):
|
|
|
|
"Implementation of the Example threading Cap'n Proto interface."
|
|
|
|
def subscribeStatus(self, subscriber, **kwargs):
|
|
return capnp.getTimer().after_delay(10**9) \
|
|
.then(lambda: subscriber.status(True)) \
|
|
.then(lambda _: self.subscribeStatus(subscriber))
|
|
|
|
def longRunning(self, **kwargs):
|
|
return capnp.getTimer().after_delay(3 * 10**9)
|
|
|
|
|
|
async def myreader(server, reader):
|
|
while True:
|
|
data = await reader.read(4096)
|
|
# Close connection if 0 bytes read
|
|
if len(data) == 0:
|
|
server.close()
|
|
await server.write(data)
|
|
|
|
|
|
async def mywriter(server, writer):
|
|
while True:
|
|
data = await server.read(4096)
|
|
writer.write(data.tobytes())
|
|
await writer.drain()
|
|
|
|
|
|
async def myserver(reader, writer):
|
|
# Start TwoPartyServer using TwoWayPipe (only requires bootstrap)
|
|
server = capnp.TwoPartyServer(bootstrap=ExampleImpl())
|
|
|
|
# Assemble reader and writer tasks, run in the background
|
|
coroutines = [myreader(server, reader), mywriter(server, writer)]
|
|
asyncio.gather(*coroutines, return_exceptions=True)
|
|
|
|
await server.poll_forever()
|
|
|
|
|
|
def parse_args():
|
|
parser = argparse.ArgumentParser(usage='''Runs the server bound to the\
|
|
given address/port ADDRESS. ''')
|
|
|
|
parser.add_argument("address", help="ADDRESS:PORT")
|
|
|
|
return parser.parse_args()
|
|
|
|
|
|
async def main():
|
|
address = parse_args().address
|
|
host = address.split(':')
|
|
addr = host[0]
|
|
port = host[1]
|
|
|
|
# Setup SSL context
|
|
ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
|
|
ctx.load_cert_chain('selfsigned.cert', 'selfsigned.key')
|
|
|
|
# Handle both IPv4 and IPv6 cases
|
|
try:
|
|
print("Try IPv4")
|
|
server = await asyncio.start_server(
|
|
myserver,
|
|
addr, port,
|
|
ssl=ctx,
|
|
)
|
|
except Exception:
|
|
print("Try IPv6")
|
|
server = await asyncio.start_server(
|
|
myserver,
|
|
addr, port,
|
|
ssl=ctx,
|
|
family=socket.AF_INET6,
|
|
)
|
|
|
|
async with server:
|
|
await server.serve_forever()
|
|
|
|
if __name__ == '__main__':
|
|
asyncio.run(main())
|