我正在尝试使用超简单的websocket将全局鼠标光标位置流式传输到Web客户端。
这两种情况都发生了,并且我的客户端(使用JS)工作正常,但是我不知道如何连接它们;每当调用move()
时,我都想发送一个websocket消息,但是我尝试的所有操作都会引发错误。
此代码打印出鼠标位置并运行websocket,但是如何使两者相互“交谈”?
import asyncio
import websockets
from pynput import mouse
def onmove(x, y):
print(x,y)
async def socket_handler(websocket, path):
while True:
message = await websocket.recv()
print(f"Received {message}")
resp = f'WS Message Was: {message}'
await websocket.send(resp)
listener = mouse.Listener(on_move = onmove)
listener.start()
start_server = websockets.serve(socket_handler, "127.0.0.1", 5000)
asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()
我觉得肯定有一个非常明显的答案,我只是不了解异步和事件循环而已
答案 0 :(得分:1)
您有很多线程与pynput和asyncio一起运行。要跨线程共享数据,您需要一个线程安全的容器。一种选择是python的queue模块。
从asyncio的角度来看,更好的选择(如user4815162342的注释所指出)是在您的其他线程的asyncio的event_loop上使用asyncio的Queue和call_soon_threadsafe。这是一个示例:
import asyncio
import json
import websockets
from pynput import mouse
q = asyncio.Queue()
def onmove(x, y):
loop.call_soon_threadsafe(q.put_nowait, (x,y))
async def socket_handler(websocket, path):
while True:
message = await q.get()
await websocket.send(json.dumps(message))
loop = asyncio.get_event_loop()
start_server = websockets.serve(socket_handler, "127.0.0.1", 5000)
loop.run_until_complete(start_server)
listener = mouse.Listener(on_move = onmove)
listener.start()
loop.run_forever()
使用标准队列的旧示例。
example_server.py
import asyncio
import queue
import json
import websockets
from pynput import mouse
q = queue.SimpleQueue()
def onmove(x, y):
try:
print("Putting: {0}".format((x,y)))
q.put((x,y), block=False)
except q.Full:
print("Dropped coords: {0}".format((x,y)))
async def getCoords():
coords = None
try:
coords = q.get(block=False)
except queue.Empty:
# print("QUEUE EMPTY")
pass
return coords
async def socket_handler(websocket, path):
while True:
message = await getCoords()
if message:
await websocket.send(json.dumps(message))
listener = mouse.Listener(on_move = onmove)
listener.start()
loop = asyncio.get_event_loop()
start_server = websockets.serve(socket_handler, "127.0.0.1", 5000)
loop.run_until_complete(start_server)
loop.run_forever()
example_client.html
<html>
<head>
<script
src="https://code.jquery.com/jquery-3.4.1.min.js"
integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo="
crossorigin="anonymous"></script>
<script>
$(function() {
var exampleSocket = new WebSocket("ws://127.0.0.1:5000");
exampleSocket.onmessage = function (event) {
var coords = JSON.parse(event.data);
$('#x').html(coords[0]);
$('#y').html(coords[1]);
};
});
</script>
</head>
<body>
<p>X: <span id="x"></span></p>
<p>Y: <span id="y"></span></p>
</body>
</html>