#python #winsound #simplehttprequesthandler
#python #winsound #simplehttprequesthandler
Вопрос:
Я не могу понять, как заставить этот маленький http-сервер отвечать на запрос get и параллельно воспроизводить звук.
Текущий код не закрывает запрос get до тех пор, пока не прозвучит звук «winsound.Воспроизведение звука («SystemExit», winsound.SND_ALIAS)» завершите воспроизведение.
Мне нужно, чтобы звук был асинхронным с запросом, чтобы запрос get завершился как можно скорее, и звук продолжал воспроизводиться.
#!/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()
Ответ №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))
Ответ №2:
ФОН
Итак, в основном, это вопрос о области выполнения в Python. Вернемся к вашему приведенному выше коду: для завершения запроса он должен выполнить все задачи.
- отправить ответ (этот ответ не действует, потому что вы должны вернуть результат из метода get)
- настройка заголовков
- воспроизведение музыки
Очевидно, что вы возвращаетесь в конце выполнения запроса, и ваш поток отслеживает только один. Таким образом, запрос завершится после завершения всех задач.
РЕШЕНИЕ
Итак, как вы упомянули в вопросе, вы правы. Чтобы воспроизвести музыку на вашем сервере по запросу, вы должны запустить асинхронную задачу и разрешить запрашивать результат возврата из запроса get. Например, с помощью 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()
Комментарии:
1. У меня это не работает, протестировал ваш код, вставив его напрямую, и не работает
2. @user8459020 Какие-либо сбои или исключения? Или звук просто не работает.
3. @user8459020 обновленный код выше, просто небольшая опечатка