简体   繁体   English

Python websocket-client 在服务器重启后重新连接

[英]Python websocket-client reconnect after server restart

I want to implement a client-server application with Python(client) and Spring Boot(Server) over websockets.我想用 Python(客户端)和 Spring Boot(服务器)在 websockets 上实现一个客户端-服务器应用程序。 I want client to try to connect server even if it is stopped, has network problems etc.我希望客户端尝试连接服务器,即使它已停止,有网络问题等。

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()

In above:在上面:

  • Case 1: Server is not working and client tries to connect ✔️案例1:服务器不工作,客户端尝试连接✔️
  • Case 2: Server starts working and client connects ✔️案例2:服务器开始工作,客户端连接✔️
  • Case 3: Server is stopped and client tries to connect x情况 3:服务器停止,客户端尝试连接x

In the 3rd case after server closed, on_open method is invoked very oddly.在服务器关闭后的第三种情况下,非常奇怪地调用了on_open方法。 Is there any solution or different way?有什么解决方案或不同的方法吗?

Thanks.谢谢。

After release 1.4.0 of websocket-client , the problem is fixed. websocket-client 1.4.0发布后,问题得到修复。 You don't even need to use thread in order to provide continuous tries for reconnecting to server.您甚至不需要使用线程来提供重新连接到服务器的连续尝试。

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