I am trying to run a websockets server and an http server in the same python application. It looks like I'm trying to run two forever loops and the 2nd loop is not getting activated. Any advice on how I can get both of these servers running?
httpd = HTTPServer(('localhost', 8000), SimpleHTTPRequestHandler)
httpd.serve_forever()
asyncio.get_event_loop().run_until_complete(
websockets.serve(echo, 'localhost', 8001))
asyncio.get_event_loop().run_forever()
Here is one way to serve both websockets and http requests with one server. The only difference with what you proposed is that both handlers listen on the same port.
I reckon it's possible to listen to separate ports by defining two aiohttp applications. However, you will in any case need an asyncio-capable HTTP server. AFAIK HTTPServer is not asyncio-enabled, so your proposed solution cannot work, since you are mixing an asyncio-based server (websockets.serve) with a non-async one (HTTPServer).
#!/usr/bin/python3.7
import aiohttp
from aiohttp import web, WSCloseCode
import asyncio
async def http_handler(request):
return web.Response(text='Hello, world')
async def websocket_handler(request):
ws = web.WebSocketResponse()
await ws.prepare(request)
async for msg in ws:
if msg.type == aiohttp.WSMsgType.TEXT:
if msg.data == 'close':
await ws.close()
else:
await ws.send_str('some websocket message payload')
elif msg.type == aiohttp.WSMsgType.ERROR:
print('ws connection closed with exception %s' % ws.exception())
return ws
def create_runner():
app = web.Application()
app.add_routes([
web.get('/', http_handler),
web.get('/ws', websocket_handler),
])
return web.AppRunner(app)
async def start_server(host="127.0.0.1", port=1337):
runner = create_runner()
await runner.setup()
site = web.TCPSite(runner, host, port)
await site.start()
if __name__ == "__main__":
loop = asyncio.get_event_loop()
loop.run_until_complete(start_server())
loop.run_forever()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With