1

我不知道如何让这个小型 http 服务器回复 get 请求并并行播放声音。

当前代码,直到声音 "winsound.PlaySound("SystemExit", winsound.SND_ALIAS)" 结束播放才关闭获取请求。

我需要的是声音与请求异步,以便获取请求尽快结束并且声音继续播放。

#!/usr/bin/env python3

from http.server import HTTPServer, SimpleHTTPRequestHandler, test
import socketserver
from urllib.parse import urlparse
from urllib.parse import parse_qs
import sys
import winsound



class MyHttpRequestHandler(SimpleHTTPRequestHandler):
    try:

        def do_GET(self):
            # Sending an '200 OK' response
            self.send_response(200)

            # Setting the header
            self.send_header("Content-type", "text/html")

            # Whenever using 'send_header', you also have to call 'end_headers'
            self.end_headers()


            html = "ok"
            # Writing the HTML contents with UTF-8
            self.wfile.write(bytes(html, "utf8"))            
            winsound.PlaySound("SystemExit", winsound.SND_ALIAS)

            return

    except Exception as e:
        print(str(e))



# Create an object of the above class
handler_object = MyHttpRequestHandler

PORT = 8000
my_server = socketserver.TCPServer(("", PORT), handler_object)

# Star the server
my_server.serve_forever()
4

2 回答 2

1

使用一个标志来异步运行它:

winsound.PlaySound("SystemExit", winsound.SND_ALIAS|winsound.SND_ASYNC)

如果您希望进行更严格的控制,请使用concurrent.futures.ThreadPoolExecutor()在不同的线程中运行它:

from concurrent.futures import ThreadPoolExecutor
import winsound

pool = ThreadPoolExecutor()

class MyHttpRequestHandler(SimpleHTTPRequestHandler):
    try:

        def do_GET(self):
            # Sending an '200 OK' response
            self.send_response(200)

            # Setting the header
            self.send_header("Content-type", "text/html")

            # Whenever using 'send_header', you also have to call 'end_headers'
            self.end_headers()


            html = "ok"
            # Writing the HTML contents with UTF-8
            self.wfile.write(bytes(html, "utf8"))

            pool.submit(winsound.PlaySound, "SystemExit", winsound.SND_ALIAS)

            return

    except Exception as e:
        print(str(e))
于 2021-01-14T11:43:08.637 回答
1

背景

所以基本上,这是关于 Python 中执行范围的问题。回到上面的代码,为了完成请求,它必须执行所有任务。

  • 发送响应(这个不生效,因为你必须从方法get返回结果)
  • 设置标题
  • 玩音乐

显然,您在请求执行结束时返回,而您的线程监视器只有一个。所以请求将在完成所有任务后完成。

解决方案

所以正如你在问题中提到的,你是对的。要根据请求在服务器上播放音乐,您必须运行异步任务并让您从 get request 请求返回结果。例如。通过使用asyncio(这是非常方便的库,所以检查一下)

import asyncio
import socketserver
from http.server import SimpleHTTPRequestHandler
import winsound


class MyHttpRequestHandler(SimpleHTTPRequestHandler):
    try:

        def do_GET(self):
            self.send_response(200)
            self.wfile.write(bytes("Ok", "utf8"))

            # Shared Queue of Background Tasks
            asyncio.get_event_loop().run_until_complete(
                MyHttpRequestHandler.play_music()
            )

    except Exception as e:
        print(str(e))

    @staticmethod
    async def play_music():
        try:
            print('Playing sound!')
            winsound.PlaySound("SystemExit", winsound.SND_ALIAS)

        # Maybe you want to add Error handling
        finally:
            pass


# Create an object of the above class
handler = MyHttpRequestHandler


server = socketserver.TCPServer(
    ("", 8000), handler)


# Star the server
server.serve_forever()
于 2021-01-11T07:27:32.387 回答