”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > 将 WebSocket 与 Python 结合使用

将 WebSocket 与 Python 结合使用

发布于2024-11-08
浏览:485

Using WebSocket with Python

什么是 WebSocket?

WebSocket 是一种支持浏览器和服务器之间实时、双向通信的协议。传统的 HTTP 通信涉及客户端发送请求和服务器响应以交换数据。相比之下,使用 WebSocket,一旦建立了初始连接,客户端和服务器都可以相互发送和接收消息,而无需重复建立新连接。

最近,OpenAI Realtime API 和 Hume AI 等交互式服务变得更加普遍,预计 WebSocket 的需求将会增加。本文介绍了如何使用 WebSocket 的基础知识,并介绍了相关的异步处理。

将 WebSocket 与 Python 结合使用

在Python中,可以使用WebSocket,如下所示:

import asyncio
import websockets

uri = "ws://..."

async def hello():
    async with websockets.connect(uri) as websocket:
        await websocket.send("Hello, Server!")
        response = await websocket.recv()
        print(f"Server says: {response}")

asyncio.run(hello())
  1. 使用 websockets.connect(uri) 连接到 WebSocket 服务器。
  2. 使用 websocket.send(message) 发送消息。
  3. 使用 websocket.recv() 接收消息。

异步处理

前面代码中使用的async和await表示异步处理。异步处理在同时执行多个任务时特别有效。

import asyncio

async def task1():
    print("Task 1: Start")
    await asyncio.sleep(2)  # Wait for 2 seconds
    print("Task 1: End")

async def task2():
    print("Task 2: Start")
    await asyncio.sleep(1)  # Wait for 1 second
    print("Task 2: End")

async def main():
    await asyncio.gather(task1(), task2())

asyncio.run(main())

在使用await的函数中,其他任务可以在等待当前任务完成的同时运行。这允许任务之间的高效切换。

异步处理和多线程

多线程也可以处理多个任务,但线程的利用方式有所不同:

  • 在多线程中,每个任务都有自己的线程,程序在等待某些进程完成的同时在任务之间切换。
  • 另一方面,异步处理不会创建新线程,而是在任务之间切换。

多线程在处理 CPU 密集型或阻塞操作时非常有效。然而,它也有缺点,例如线程切换(上下文切换)的开销和增加的内存消耗。

相反,异步处理减少了上下文切换的开销,因为它不依赖于线程。但是,如果正在运行繁重的任务,其他任务可能需要等待。因此,它适合 IO 密集型操作,例如 API 请求。

(对于计算密集型或需要精确计时的任务,多处理通常更有效。与多线程不同,多处理允许多个任务同时运行。)

例如,当使用OpenAI Realtime API实时接收来自麦克风的音频并将音频数据发送到API时,可以使用多线程和异步处理的组合:

import asyncio
import threading
import queue
import pyaudio
import websockets

# Use a queue to share data between threads
audio_queue = queue.Queue()

# Thread to capture audio using PyAudio
def audio_stream():
    p = pyaudio.PyAudio()
    stream = p.open(format=pyaudio.paInt16,
                    channels=1,
                    rate=44100,
                    input=True,
                    frames_per_buffer=1024)

    print("Start recording...")
    while True:
        data = stream.read(1024)
        audio_queue.put(data)

# Asynchronous function to send audio data via WebSocket
async def send_audio():
    uri = "ws://localhost:8765"
    async with websockets.connect(uri) as websocket:
        while True:
            # Get audio data from the queue
            data = audio_queue.get()
            if data is None:
                break
            await websocket.send(data)
            print("Sent audio data")

# Start the audio capture thread and run the asynchronous task
def main():
    audio_thread = threading.Thread(target=audio_stream)
    audio_thread.start()

    # Run the WebSocket sending task
    asyncio.run(send_audio())

if __name__ == "__main__":
    main()

音频捕获过程是一个阻塞操作,因此它是使用线程在单独的线程中执行的。相比之下,发送音频数据涉及 IO 绑定操作(例如与 API 交互),是使用异步处理完成的。 (注意:PyAudio 也可以使用回调以非阻塞方式运行。)

结论

在这篇文章中,我们介绍了WebSocket和异步处理。

我发现这些概念在使用 OpenAI Realtime API 时特别令人困惑,因此我将其作为个人笔记放在一起。如果您发现任何错误或有任何反馈,我将不胜感激您的意见。

感谢您阅读到最后。

版本声明 本文转载于:https://dev.to/m_sea_bass/using-websocket-with-python-42b7?1如有侵犯,请联系[email protected]删除
最新教程 更多>
  • 如何处理 Java 中的“无法将给定对象格式化为日期”错误?
    如何处理 Java 中的“无法将给定对象格式化为日期”错误?
    处理 Java 中的“无法将给定对象格式化为日期”错误当尝试将给定日期转换为特定格式时,Java 开发人员可能会遇到异常: “java.lang.IllegalArgumentException:无法将给定对象格式化为日期。”当尝试将不受支持的对象格式化为日期时,会出现此错误。要解决此问题,我们需要...
    编程 发布于2024-11-08
  • RPC 操作 EPU 使用 Protobuf 并创建自定义插件
    RPC 操作 EPU 使用 Protobuf 并创建自定义插件
    上一篇文章中,我使用net/rpc包实现了一个简单的RPC接口,并尝试了net/rpc自带的Gob编码和JSON编码,学习了Golang的一些基础知识远程过程调用。在这篇文章中,我将结合 net/rpc 和 protobuf 并创建我的 protobuf 插件来帮助我们生成代码,所以让我们开始吧。 ...
    编程 发布于2024-11-08
  • 无需媒体查询的响应式布局
    无需媒体查询的响应式布局
    How often do you use media queries when building web layouts? I’ve spent too much time on them! First you spent quite a lot of time trying to make the...
    编程 发布于2024-11-08
  • 使用 JavaScript 更改锚标记 href 属性时如何防止页面重新加载?
    使用 JavaScript 更改锚标记 href 属性时如何防止页面重新加载?
    点击按钮时使用JavaScript更改锚标签的href属性在web开发中,需要动态修改锚标签的href属性按钮点击时经常出现锚标签。以下是使用 JavaScript 实现此目的的方法。在提供的代码片段中,f1() 函数将 ID 为“abc”的元素的 href 属性更改为“xyz.php”。但是,提供...
    编程 发布于2024-11-08
  • 使用 Sheepy 在 Python 中进行单元测试
    使用 Sheepy 在 Python 中进行单元测试
    大家好,今天我来给大家介绍一个新的单元测试库,叫做sheepy,不过首先我们来说说单元测试的重要性。这个库不适合初学者,要使用它进行单元测试,您需要额外注意。它仅具有用于使用端点和 http 错误检查模块进行 API 测试的断言。 Github链接:github PyPi 链接:pypi 生产中所有...
    编程 发布于2024-11-08
  • 为什么“pch.h”应该成为 C/C++ 项目中的第一个头文件?
    为什么“pch.h”应该成为 C/C++ 项目中的第一个头文件?
    预编译头:理解“pch.h”在C和C语言开发中,“pch.h”代表预编译头文件。将其作为第一个头文件包含在编译速度方面具有显着的优势。什么是预编译头?预编译头是头的中间形式编译器生成的文件。它包含优化编译过程的编译信息,特别是对于大型或大量包含的头文件。为什么包含“pch.h”作为第一个头文件?在 ...
    编程 发布于2024-11-08
  • 探索 JVM 虚拟线程机制中的固定
    探索 JVM 虚拟线程机制中的固定
    Java 的虚拟线程提供了传统操作系统线程的轻量级替代方案,从而实现了高效的并发管理。但了解他们的行为对于获得最佳表现至关重要。这篇博文深入探讨了固定(一种可能影响虚拟线程执行的场景),并探讨了监控和解决该问题的技术。 虚拟线程:一种轻量级并发方法 Java 的虚拟线程是运行在底层操...
    编程 发布于2024-11-08
  • 如何在不使用分析函数的情况下高效地选择 MySQL 中每个类别的前几行?
    如何在不使用分析函数的情况下高效地选择 MySQL 中每个类别的前几行?
    在 MySQL 中选择每个类别的前几行要从表中的每个类别中检索有限数量的行,您可以使用分析函数。然而,MySQL 并不直接提供这些功能。不过,可以使用变量来模拟它们。模拟分析函数以下 MySQL 查询模拟分析函数的功能,以选择每个类别的前 3 行:SELECT x.* FROM ( SELE...
    编程 发布于2024-11-08
  • 了解 JavaScript 中的异步编程:事件循环初学者指南
    了解 JavaScript 中的异步编程:事件循环初学者指南
    Have you ever wondered why some pieces of JavaScript code seem to run out of order? The key to understanding this is the event loop. JavaScript's even...
    编程 发布于2024-11-08
  • 如何使用 multiprocessing.Manager 在多个进程之间共享结果队列?
    如何使用 multiprocessing.Manager 在多个进程之间共享结果队列?
    使用 multiprocessing.Manager 在多个进程之间共享结果队列在多处理中,父子进程之间共享队列对于通信和结果检索至关重要。然而,使用 apply_async 启动异步工作进程在共享队列方面提出了挑战。为了克服“队列对象只能通过继承在进程之间共享”错误,我们可以利用 multipro...
    编程 发布于2024-11-08
  • 如何在Visual Studio Code中设置Python调试的工作目录?
    如何在Visual Studio Code中设置Python调试的工作目录?
    如何设置使用 VS Code 的调试器调试 Python 程序的工作目录?使用 Visual Studio Code 调试 Python 程序时 ( VS Code),指定工作目录对于确保脚本正确运行至关重要。要在启动配置文件 (launch.json) 中设置工作目录,请按照以下步骤操作: 打开 ...
    编程 发布于2024-11-08
  • 为什么 Matplotlib 的动画代码使用尾随逗号?
    为什么 Matplotlib 的动画代码使用尾随逗号?
    揭开Matplotlib动画中的尾随逗号:它是逗号运算符吗?在使用Matplotlib创建简单动画的代码片段中,变量行后面可以观察到逗号:line, = ax.plot(x, np.sin(x))这个逗号让一些开发者感到困惑,导致有人质疑它是否代表逗号运算符。消除逗号运算符神话此上下文中的尾随逗号并...
    编程 发布于2024-11-08
  • 在 Laravel 中将花式文本标准化为普通文本
    在 Laravel 中将花式文本标准化为普通文本
    文章源自https://medium.com/@hafiqiqmal93/normalizing-fancy-text-to-normal-text-in-laravel-7d9ed56d5a78 用户输入的文本一点也不有趣。随着 Unicode 在智能手机中的出现,用户现在可以奢侈地(有时甚至是...
    编程 发布于2024-11-08
  • 4 种顶级 API 测试工具指南
    4 种顶级 API 测试工具指南
    在 API 测试方面,拥有正确的工具可以带来巨大的改变。在本文中,我们将探讨 2024 年可用的一些最佳 API 测试工具,适合各个级别的开发人员。 回声API EchoAPI 是一种新兴且快速发展的 API 开发协作工具。与 Postman 不同,它有几个明显的优势,使其成为 P...
    编程 发布于2024-11-08
  • 如何解决多项目 Gradle 配置中的测试依赖关系?
    如何解决多项目 Gradle 配置中的测试依赖关系?
    解决多项目 Gradle 配置中的测试依赖关系在 Gradle 中处理多项目构建时,必须在跨项目的测试代码之间建立有效的依赖关系。考虑项目 A 和项目 B 存在的场景,项目 B 依赖于项目 A 的组件。问题陈述在这种情况下,项目 B 的 build.gradle 可能如下所示:apply plugi...
    编程 发布于2024-11-08

免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

Copyright© 2022 湘ICP备2022001581号-3