簡體   English   中英

Python websocket-client 在服務器重啟后重新連接

[英]Python websocket-client reconnect after server restart

我想用 Python(客戶端)和 Spring Boot(服務器)在 websockets 上實現一個客戶端-服務器應用程序。 我希望客戶端嘗試連接服務器,即使它已停止,有網絡問題等。

import time
from threading import Thread, Event

import rel
import stomper
import websocket
import logging

class ClientSocket:
 def __init__(self):
    self.opened = None
    self.thread = None
    self.opened = False
    self.try_connecting = Event()
    self.ws = websocket.WebSocketApp("ws://localhost:8080/socket",
                                     header={
                                         'Authorization': 'Bearer eyJhbGciOiJIUzUxMiJ9.ey'},
                                     on_open=self.on_open,
                                     on_message=self.on_message,
                                     on_error=self.on_error,
                                     on_close=self.on_close)
    # self.rel = rel
    self.ws.run_forever(dispatcher=rel)
    rel.signal(2, rel.abort)  # Keyboard Interrupt
    rel.dispatch()

def on_message(self, ws, message):
    print(message)

def on_error(self, ws, error):
    print(error)

def on_close(self, ws, close_status_code, close_msg):
    print("### closed ###")
    if self.opened:
        self.connect_abort_server()
    if not self.try_connecting.is_set():
        self.try_connecting.set()
        self.auto_reconnect()

def on_open(self, ws):
    self.opened = True
    if self.try_connecting.is_set():
        self.try_connecting.clear()
    print("Opened connection")
    time.sleep(2)
    ws.send("CONNECT\naccept-version:1.0,1.1,2.0\n\n\x00\n")

    # Subscribing to all required desitnations.
    sub = stomper.subscribe("/user/queue/reply", "clientuniqueId", ack="auto")
    ws.send(sub)

def connect_abort_server(self):
    self.opened = False
    rel.abort()
    self.ws.close()
    self.ws = websocket.WebSocketApp("ws://localhost:8080/socket",
                                     header={
                                         'Authorization': 'Bearer eyJhbGciOiJIUzUxMiJ9.ey'},
                                     on_open=self.on_open,
                                     on_message=self.on_message,
                                     on_error=self.on_error,
                                     on_close=self.on_close)

def thread_func(self):
    while self.try_connecting.is_set():
        try:
            self.ws.run_forever(dispatcher=rel)  # Set dispatcher to automatic reconnection
            # self.rel.signal(2, self.rel.abort)  # Keyboard Interrupt
            # rel.dispatch()
            time.sleep(2)
            print('Worker thread running...')
        except ConnectionResetError:
            print("==> ConnectionResetError")
            pass
    print('Worker closing down')

def auto_reconnect(self):
    self.thread = Thread(target=self.thread_func())
    self.thread.daemon = True
    time.sleep(2)
    self.thread.start()


if __name__ == "__main__":
   LOG_FORMAT = "%(asctime)s - %(levelname)s - %(message)s"
   logging.basicConfig(level=logging.DEBUG, format=LOG_FORMAT)
   client_socket = ClientSocket()

在上面:

  • 案例1:服務器不工作,客戶端嘗試連接✔️
  • 案例2:服務器開始工作,客戶端連接✔️
  • 情況 3:服務器停止,客戶端嘗試連接x

在服務器關閉后的第三種情況下,非常奇怪地調用了on_open方法。 有什么解決方案或不同的方法嗎?

謝謝。

websocket-client 1.4.0發布后,問題得到修復。 您甚至不需要使用線程來提供重新連接到服務器的連續嘗試。

class ClientSocket:
    def __init__(self):
        self.opened = False
        self.ws = websocket.WebSocketApp("ws://localhost:8080/socket",
                                         header={
                                             'Authorization': 'Bearer eyJhbGciOiJIUzUxMiJ9'},
                                         on_open=self.on_open,
                                         on_message=self.on_message,
                                         on_error=self.on_error,
                                         on_close=self.on_close)
        self.ws.run_forever(dispatcher=rel)
        rel.signal(2, rel.abort)  # Keyboard Interrupt
        rel.dispatch()

    def on_message(self, ws, message):
        print(message)

    def on_error(self, ws, error):
        print(error)

    def on_close(self, ws, close_status_code, close_msg):
        print("### closed ###")
        rel.abort()
        self.ws.run_forever(dispatcher=rel)
        rel.signal(2, rel.abort)
        rel.dispatch()

    def on_open(self, ws):
        print("Opened connection")
        time.sleep(2)
        ws.send("CONNECT\naccept-version:1.0,1.1,2.0\n\n\x00\n")

        # Subscribing to all required desitnations.
        sub = stomper.subscribe("/user/queue/reply", "clientuniqueId", ack="auto")
        ws.send(sub)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM