Reputation: 330
I have this small snippet which I intend to have function as a server, I have managed to get the socket to connect to the client but cannot send data due to errors.
import asyncio
import json
import socketio
from aiohttp import web
ALLOWED_ORIGINS = ["http://localhost:45100"]
sio = socketio.AsyncServer(cors_allowed_origins=ALLOWED_ORIGINS)
app = web.Application()#socketio.ASGIApp(sio)
sio.attach(app)
@sio.event
async def connect(sid, environ):
origin=environ.get('HTTP_ORIGIN', '')
if origin not in ALLOWED_ORIGINS:
print(f'Connection from {origin} imetupwa')
await sio.disconnect(sid)
else:
print(f'Allowing connection from {origin}')
@sio.event
async def disconnect(sid):
print('Disconnected', sid)
async def send_gpio_data():
print('Going to send data')
try:
while True:
data = {'speed': 100}
await sio.emit('ecuData', json.dumps(data))
print("Data sent, sleeping...")
await asyncio.sleep(1)
except Exception as error:
print(f'Error in sending data: {error}')
async def main():
print('Init main')
asyncio.create_task(send_gpio_data())
runner = web.AppRunner(app)
await runner.setup()
site = web.TCPSite(runner, '0.0.0.0', 8090)
print("Web app running on http://0.0.0.0:8090")
await site.start()
await asyncio.Event().wait()
if __name__ == '__main__':
try:
asyncio.run(main())
except KeyboardInterrupt:
print("Done!")
Here is the putout:
Init main
Web app running on http://0.0.0.0:8090
Going to send data
Data sent, sleeping...
Allowing connection from http://localhost:45100
Error in sending data: Passing coroutines is forbidden, use tasks explicitly.
/Users/keronei/StudioProjects/Side Projects/rotor/server.py:35: RuntimeWarning: coroutine 'AsyncServer._emit_internal' was never awaited
print(f'Error in sending data: {error}')
RuntimeWarning: Enable tracemalloc to get the object allocation traceback
The execution stops right after the crash, I have also tried sio.start_background_task(send_gpio_data)
but I get the same error.
Upvotes: 1
Views: 102
Reputation: 330
I found the problem to be an incompatible asyncio
with Python
version.
On a random search, someone responded to the same issue on Medium with the following comment, I presume the commenter is a maintainer/contributor:
...but for this error, I suspect that it's because the Python version I've used for the template was below 3.11. For me, I used 3.10. Could you downgrade the Python version (by creating another virtualenv) and try it out with a different version?
From this, I re-created the virtual environment with Python 3.9 and the error went away.
This is just a fix, but there should be a correct approach for Python 3.10 and up.
If curious, here is what I did (on Mac):
which -a python python3
This returns a list of installation locations, I picked each of them (to figure out if there was 3.10 or below)
$ /usr/local/bin/python3
This opens a Python environment with the version indicated.
virtualenv -p /usr/bin/python3 env
I then activated and ran the script and the error was gone.
Upvotes: 0
Reputation: 1
import asyncio
import json
import socketio
from aiohttp import web
ALLOWED_ORIGINS = ["http://localhost:45100"]
sio = socketio.AsyncServer(cors_allowed_origins=ALLOWED_ORIGINS)
app = web.Application()
sio.attach(app)
@sio.event
async def connect(sid, environ):
origin = environ.get('HTTP_ORIGIN', '')
if origin not in ALLOWED_ORIGINS:
print(f'Connection from {origin} rejected')
await sio.disconnect(sid)
else:
print(f'Allowing connection from {origin}')
@sio.event
async def disconnect(sid):
print('Disconnected', sid)
async def send_gpio_data():
print('Going to send data')
try:
while True:
data = {'speed': 100}
await sio.emit('ecuData', data) # No need to json.dumps, just send dict
print("Data sent, sleeping...")
await asyncio.sleep(1)
except Exception as error:
print(f'Error in sending data: {error}')
async def main():
print('Init main')
# Schedule the coroutine to run in the background
sio.start_background_task(send_gpio_data)
runner = web.AppRunner(app)
await runner.setup()
site = web.TCPSite(runner, '0.0.0.0', 8090)
print("Web app running on http://0.0.0.0:8090")
await site.start()
await asyncio.Event().wait()
if __name__ == '__main__':
try:
asyncio.run(main())
except KeyboardInterrupt:
print("Done!")
Upvotes: -1