Python中的Websockets服务器推送

sc4hvdpw  于 2023-05-29  发布在  Python
关注(0)|答案(2)|浏览(221)

我如何用Python编写一个Websockets服务器,它只是在定时间隔内将数据推送到所有连接的客户端,而不等待任何传入的消息?

e5nqia27

e5nqia271#

我在回答我自己的问题...
这是一个Python websockets服务器的工作示例,它每5秒向所有客户端发送一条消息。我写了这个,并设法让它工作,因为我在网上找不到一个这样的例子(2021年3月)
希望这对其他人有帮助,如果任何人有改进或更好的解决方案的建议,使用软件包,可能添加ssl支持或订阅类型的服务添加,请在评论或回答部分写。

import asyncio
import logging
import websockets
from websockets import WebSocketServerProtocol
import time
import threading

logging.basicConfig(level=logging.INFO)

class Server:

    clients = set()
    logging.info(f'starting up ...')

    def __init__(self):
        logging.info(f'init happened ...')
        
    async def register(self, ws: WebSocketServerProtocol) -> None:
        self.clients.add(ws)
        logging.info(f'{ws.remote_address} connects')

    async def unregister(self, ws: WebSocketServerProtocol) -> None:
        self.clients.remove(ws)
        logging.info(f'{ws.remote_address} disconnects')

    async def send_to_clients(self, message: str) -> None:
        if self.clients:
            logging.info("trying to send")
            await asyncio.wait([client.send(message) for client in self.clients])

    async def ws_handler(self, ws: WebSocketServerProtocol, url: str) -> None:
        await self.register(ws)
        try:
            await self.distribute(ws)
        finally:
            await self.unregister(ws)

    async def distribute(self, ws: WebSocketServerProtocol) -> None:
        async for message in ws:
            await self.send_to_clients(message)

async def timerThread(server,counter):
    counter = 0
    while True:
        await checkAndSend(server,counter)
        print("doing " + str(counter))
        time.sleep(5)
        counter = counter + 1

async def checkAndSend(server,counter):
    # check something
    # send message
    logging.info("in check and send")
    await server.send_to_clients("Hi there: " + str(counter))

# helper routine to allow thread to call async function
def between_callback(server,counter):
    loop = asyncio.new_event_loop()
    asyncio.set_event_loop(loop)
    loop.run_until_complete(timerThread(server,counter))
    loop.close()

# start server
server = Server()
start_server = websockets.serve(server.ws_handler,'localhost',4000)
counter = 0 

# start timer thread
threading.Thread(target=between_callback,args=(server,counter,)).start()

# start main event loop
loop = asyncio.get_event_loop()
loop.run_until_complete(start_server)
loop.run_forever()

要查看其工作情况,您可以使用这个简单的html文件作为客户端,然后打开检查器以查看Console日志中的传入消息。

<h1> Websocket Test </h1>
<script>
const ws = new WebSocket('ws://localhost:4000')
ws.onopen = () => {
  console.log('ws opened on browser')
  ws.send('hello world')
}
ws.onmessage = (message) => {
  console.log(`message received`, message.data)
}
</script>

如果你使用的是python 3.11,下面的函数应该像这样重写:

async def send_to_clients(self, message: str) -> None:
    if self.clients:
        logging.info("trying to send")
        [await client.send(message) for client in self.clients]
relj7zay

relj7zay2#

from datetime import time
    import schedule
    import time
    import socket
    import threading

alarm_time = input()
my_string = str(alarm_time)
my_new_time = my_string.format("%H:%M %Z")

EADER = 64
PORT = xxxx
SERVER = 'xxxxxxxx'
ADDR = (SERVER, PORT)
FORMAT = 'utf-8'

server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(ADDR)

if alarm_time is not None and alarm_time != 0:
    print(f"Scheduled for: {my_new_time}")
else:
    sys.exit()
    
    def job():
            client.connect(ADDR)
            name_time = self.name_send + ' ' + my_date
            message = name_time.encode(FORMAT)
            msg_length = len(message)
            send_length = str(msg_length).encode(FORMAT)
            send_length += b' ' * (HEADER - len(send_length))
            client.send(send_length)
            client.send(message)
    
    
    schedule.every().day.at(my_new_time).do(job)
    
    
    while True:
        schedule.run_pending()
        time.sleep(1)

Not sure if this is any help tbh. But its a small tweak of a script I use with socket, subprocess etc to schedule them

相关问题