|  | import asyncio | 
        
          |  | from functools import wraps | 
        
          |  |  | 
        
          |  | from aiohttp import web | 
        
          |  | from websockets import handshake | 
        
          |  | from websockets import WebSocketCommonProtocol | 
        
          |  |  | 
        
          |  |  | 
        
          |  | INDEX = open('index.html').read().encode('utf-8') | 
        
          |  |  | 
        
          |  |  | 
        
          |  | class WebSocketResponse(web.Response): | 
        
          |  |  | 
        
          |  | def __init__(self, request, switch_protocols): | 
        
          |  | http11 = request._version == (1, 1) | 
        
          |  | get_header = lambda k: dict(request.headers)[k.upper()] | 
        
          |  | key = handshake.check_request(get_header) | 
        
          |  | if not http11 or not key: | 
        
          |  | super('Invalid WebSocket handshake.\n', status=400) | 
        
          |  | else: | 
        
          |  | headers = dict() | 
        
          |  | set_header = headers.__setitem__ | 
        
          |  | handshake.build_response(set_header, key) | 
        
          |  | self.switch_protocols = switch_protocols | 
        
          |  | super().__init__(status=101, headers=headers) | 
        
          |  | self._keep_alive = True | 
        
          |  | request.transport.close = switch_protocols | 
        
          |  |  | 
        
          |  |  | 
        
          |  | @asyncio.coroutine | 
        
          |  | def handle(request): | 
        
          |  | return web.Response(body=INDEX) | 
        
          |  |  | 
        
          |  |  | 
        
          |  | def websocket(handler): | 
        
          |  |  | 
        
          |  | @asyncio.coroutine | 
        
          |  | @wraps(handler) | 
        
          |  | def wrapper(request, *args, **kwargs): | 
        
          |  | transport = request.transport | 
        
          |  | http_protocol = transport._protocol | 
        
          |  |  | 
        
          |  | @asyncio.coroutine | 
        
          |  | def run_ws_handler(ws): | 
        
          |  | yield from handler(ws, request, *args, **kwargs) | 
        
          |  | yield from ws.close() | 
        
          |  |  | 
        
          |  | def switch_protocols(): | 
        
          |  | ws_protocol = WebSocketCommonProtocol() | 
        
          |  | transport._protocol = ws_protocol | 
        
          |  | ws_protocol.connection_made(transport) | 
        
          |  |  | 
        
          |  | # Ensure aiohttp doesn't interfere. | 
        
          |  | http_protocol.transport = None | 
        
          |  |  | 
        
          |  | asyncio.async(run_ws_handler(ws_protocol)) | 
        
          |  |  | 
        
          |  | return WebSocketResponse(request, switch_protocols) | 
        
          |  |  | 
        
          |  | return wrapper | 
        
          |  |  | 
        
          |  |  | 
        
          |  | @websocket | 
        
          |  | @asyncio.coroutine | 
        
          |  | def ws(ws, request): | 
        
          |  | while ws.open: | 
        
          |  | message = yield from ws.recv() | 
        
          |  | if message: | 
        
          |  | print(ws, request, message) | 
        
          |  | yield from ws.send("Hello from aiohttp powered websocket!") | 
        
          |  |  | 
        
          |  |  | 
        
          |  | @asyncio.coroutine | 
        
          |  | def init(loop): | 
        
          |  | app = web.Application(loop=loop) | 
        
          |  | app.router.add_route('GET', '/', handle) | 
        
          |  | app.router.add_route('GET', '/ws', ws) | 
        
          |  |  | 
        
          |  | server = yield from loop.create_server( | 
        
          |  | app.make_handler(), | 
        
          |  | '127.0.0.1', | 
        
          |  | 8080 | 
        
          |  | ) | 
        
          |  | print("Server started at http://127.0.0.1:8080") | 
        
          |  | return server | 
        
          |  |  | 
        
          |  |  | 
        
          |  | loop = asyncio.get_event_loop() | 
        
          |  | loop.run_until_complete(init(loop)) | 
        
          |  | loop.run_forever() |