Files
pycapnp/examples/async_ssl_server.py
Jacob Alexander 78776de647 Adding examples as pytest tests
- This way they will be included in CI checks
- Decreased the delay time in the thread-like examples to speed up tests
(probably could decrease the time some more)
- Added an async version of the calculator test
- Forcing python3 support for example scripts
2019-09-27 14:40:54 -07:00

99 lines
2.4 KiB
Python
Executable File

#!/usr/bin/env python3
from __future__ import print_function
import argparse
import os
import capnp
import thread_capnp
import asyncio
import socket
import ssl
this_dir = os.path.dirname(os.path.abspath(__file__))
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(1 * 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(os.path.join(this_dir, 'selfsigned.cert'), os.path.join(this_dir, '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())