首页 > 编程问答 >Python 请求 POST 请求与 websockets 库一起使用时挂起

Python 请求 POST 请求与 websockets 库一起使用时挂起

时间:2024-08-04 14:57:02浏览次数:16  
标签:python websocket python-requests fastapi

我使用 Python 中的 requests 库发送 POST 请求,同时维护与 websockets 库的 WebSocket 连接:

import asyncio
import requests
import websockets

async def websocket_handler(uri):
    async with websockets.connect(uri) as websocket:
        while True:
            message = await websocket.recv()
            print(f"Received message: {message}")

async def make_request():
    s = requests.Session()
    print(1)
    try:
        response = s.post('http://192.168.1.4/create', timeout=10)
        print(3)
        print(response.text)
    except requests.exceptions.Timeout:
        print("The request timed out") # this happens
    except requests.exceptions.RequestException as e:
        print(f"An error occurred: {e}")

async def main():
    websocket_task = asyncio.create_task(websocket_handler("ws://example.com/websocket"))
    request_task = asyncio.create_task(make_request())
    await asyncio.gather(websocket_task, request_task)

if __name__ == "__main__":
    asyncio.run(main())

服务器日志显示没有请求。服务器可访问且配置正确。使用带有 Websocket 的请求时可能会导致此问题的原因是什么?


问题在于你在异步代码中使用了同步请求库 requests requests.post 是一个阻塞调用,这意味着它会暂停你的事件循环,直到请求完成,从而阻止 WebSocket 处理程序接收消息。

你有几个选择可以解决这个问题:

1. 使用异步 HTTP 库:

requests 替换为像 aiohttp 这样的异步 HTTP 库,它允许你进行非阻塞请求:

```python import asyncio import aiohttp import websockets

async def websocket_handler(uri): # ...

async def make_request(): async with aiohttp.ClientSession() as session: try: async with session.post('http://192.168.1.4/create', timeout=10) as response: print(3) print(await response.text()) except asyncio.TimeoutError: print("The request timed out") except Exception as e: print(f"An error occurred: {e}")

async def main(): # ... ```

2. 在单独的线程中运行 requests

如果你不想切换到异步 HTTP 库,你可以在单独的线程中运行阻塞 requests.post 调用:

```python import asyncio import requests import websockets from concurrent.futures import ThreadPoolExecutor

async def websocket_handler(uri): # ...

def blocking_request(): try: response = requests.post('http://192.168.1.4/create', timeout=10) print(3) print(response.text) except requests.exceptions.Timeout: print("The request timed out") except requests.exceptions.RequestException as e: print(f"An error occurred: {e}")

async def make_request(): loop = asyncio.get_running_loop() with ThreadPoolExecutor() as pool: await loop.run_in_executor(pool, blocking_request)

async def main(): # ... ```

这会将阻塞调用卸载到线程池,允许事件循环继续运行,并且 WebSocket 处理程序可以接收消息。

选择哪种方法取决于你的具体需求和偏好。如果你正在构建一个需要处理大量并发请求的应用程序,那么使用 aiohttp 等异步 HTTP 库通常是更好的选择。但是,如果你只需要进行一些偶尔的请求,那么在单独的线程中运行 requests 可能更简单。

标签:python,websocket,python-requests,fastapi
From: 78830030

相关文章

  • 在Python中,list1[::] = list2的空间复杂度是多少?
    此代码首先迭代列表nums,更新整数0、1、2(也分别称为红色、白色和蓝色)的计数。nums保证只有整数0、1和/或2。找到计数后,代码使用[::],这是一种就地修改列表的技巧,以排序numsdefsortColors(self,nums:List[int])->None:re......
  • [附开题]flask框架高校资产管理系统d8y3s(源码+论文+python)
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容研究背景随着高等教育事业的快速发展,高校资产规模日益庞大,种类繁多,管理难度显著增加。传统的资产管理方式往往依赖于手工记录和纸质档案,不仅效率低......
  • [附开题]flask框架贺州图特产管理系统uuy79(源码+论文+python)
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容研究背景贺州,这座历史悠久、文化底蕴深厚的城市,以其丰富的自然资源和独特的地理位置孕育了众多令人瞩目的特产。然而,在信息化快速发展的今天,贺州特......
  • [附开题]flask框架红枫超市会员管理系统ew5iq(源码+论文+python)
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容研究背景随着零售行业的快速发展与消费者需求的日益多样化,超市作为人们日常生活中不可或缺的一部分,其管理效率和服务质量直接影响着顾客的购物体验......
  • PYTHON专题-(4)python叫你搞对象
    什么是面向过程编程?面向过程的程序设计把计算机程序视为一系列的命令集合,即一组函数的顺序执行。为了简化程序设计,面向过程把函数继续切分为子函数,即把大块函数通过切割成小块函数来降低系统的复杂度。什么是面向对象编程?面向对象编程——ObjectOrientedProgramming,简......
  • Python 基础教学:中文编码处理
    《Python基础教学:中文编码处理》在编程中,处理中文字符时经常会遇到编码问题。Python3默认使用UTF-8编码,但在处理文件、网络数据或与旧系统交互时,可能需要处理GBK、GB2312等其他编码。1.字符串的编码和解码在Python中,字符串(str)默认是Unicode编码。当你需要将......
  • Python 基础教学:深入了解 continue、break 和 pass 语句
    《Python基础教学:深入了解continue、break和pass语句》Python中的控制流语句不仅仅包括条件语句和循环,还包括continue、break和pass这三个特殊的关键字,它们在特定情况下可以控制程序的流程。1.continue语句continue用于跳过当前循环的剩余代码,在循环控制结......
  • Python 基础教程:List(列表)的使用
    《Python基础教程:List(列表)的使用》在Python中,列表是最基本的数据结构之一,它是一种有序的、可变的数据集合,可以包含任意类型的元素,包括数字、字符串、其他列表等。1.列表的创建列表使用方括号[]创建,列表中的元素用逗号,分隔。#创建一个包含整数的列表numbers......
  • kettle从入门到精通 第八十三课 ETL之kettle kettle调用python且接收返回值
    场景:kettle调用python执行脚本,处理之后,再把结果数据流发给下一个步骤。 看到有个qq群里有个小伙伴求助要实现kettle调用python脚本,然后接收python脚本执行的结果,最后将结果传递到下一个步骤。之前的课程里面介绍的是kettle通过shell步骤调用python脚本,没有接收python返回的结果......
  • Python | 函数式编程
    文章目录1函数式编程2lamda表达式(匿名函数)3偏函数4闭包和自由变量5内置函数5.1map()函数5.2reduce()函数5.3filter()函数5.4sorted函数1函数式编程函数式编程(functionalprogramming)其实是个很古老的概念,诞生距今快60年啦!最古老的函数式编程语言Lisp......