使用Docker部署Flask+SocketIO脚本时遇TypeError错误求助
解决Gunicorn运行Aiohttp应用时的
TypeError: __call__() takes 1 positional argument but 3 were given错误 问题根源
你遇到的错误核心原因是:Gunicorn默认的同步Worker(sync worker)只支持WSGI标准的Web应用,但你的app是Aiohttp的web.Application,属于ASGI异步应用,两者的调用接口不兼容,导致参数传递时出现不匹配的问题。
另外你的配置还有两个隐性问题需要修正:
requirements.txt里没明确声明aiohttp依赖(虽然aiohttp-cors会间接安装它,但明确写入依赖列表更稳妥,也能避免版本冲突);- Gunicorn命令既没指定适配Aiohttp的Worker类,也没明确绑定到和Docker映射对应的8000端口。
分步解决方案
1. 更新requirements.txt
添加aiohttp依赖(选和Python3.8兼容的3.8.6版本即可),同时可以移除代码里根本没用到的Flask、Flask-SocketIO和asyncio(Python3.8自带asyncio,无需额外安装):
aiohttp==3.8.6 aiohttp-cors==0.7.0 gunicorn==20.0.4
2. 修改Dockerfile的CMD命令
指定使用Aiohttp专用的Worker类,并明确绑定到0.0.0.0:8000(和Docker run时的端口映射5080:8000对应):
CMD ["main:app", "-b", "0.0.0.0:8000", "-k", "aiohttp.GunicornWebWorker"]
3. 优化main.py的启动逻辑
当用Gunicorn运行时,if __name__ == '__main__':块里的代码完全不会执行(因为Gunicorn是直接导入模块并使用app对象),所以可以把这部分冗余代码注释或删除:
# 移除或注释以下代码: # if __name__ == '__main__': # print("websocket server is running!") # the_asyncio_loop = asyncio.get_event_loop() # run_the_websocket = asyncio.gather(web.run_app(app)) # run_both_loops_together = asyncio.gather(run_the_websocket) # results = the_asyncio_loop.run_until_complete(run_both_loops_together)
重新部署验证
- 重新构建Docker镜像:
docker build -t websocketserver .
- 重新运行容器:
docker run -d -p 5080:8000 --restart always --name my_second_docker_running websocketserver
- 查看日志确认无错误:
docker logs my_second_docker_running
现在你的手机应该可以正常连接WebSocket服务器了。
内容的提问来源于stack exchange,提问作者jadadad
相关产品推荐
相关产品推荐

