Skip to content

WebSocket disconnects after sending ping messages #78

@OdCheban

Description

@OdCheban

Description:
I'm experiencing an issue with the Gate.io WebSocket API where the server disconnects me after I start sending ping messages to keep the connection alive.

What I'm doing:

  1. Connecting to wss://api.gateio.ws/ws/v4/
  2. Subscribing to spot.obu channel for ob.BTC_USDT.50
  3. Sending ping messages every 20 seconds in the following format:
    {
    "time": {time},
    "channel": "spot.ping"
    }

Expected behavior:
The server should respond with a pong message and keep the connection alive.

Actual behavior:
Initially, the server responds with pong messages
After some time (varies, but eventually), the server disconnects the WebSocket connection
The disconnection happens without any error message or warning...after 270 seconds

Code:

import json
import time
import threading
from datetime import datetime
from websocket import create_connection

class WebSocketLogger:
    def __init__(self):
        self.start_time = datetime.now()
        self.ws = None
        self.running = False
        
    def send_ping(self):
        while self.running:
            time.sleep(20)
            if self.running and self.ws:
                try:
                    self.ws.send(json.dumps({
                        "time": int(time.time()),
                        "channel": "spot.ping"
                    }))
                    print(f"Sent ping")
                except Exception as e:
                    print(f"Error sending ping: {e}")
                    break
    
    def run(self):
        self.ws = create_connection("wss://api.gateio.ws/ws/v4/")
        print("Connected to WebSocket")
        
        self.ws.send(json.dumps({
            "time": int(time.time()),
            "channel": "spot.obu",
            "event": "subscribe",
            "payload": ["ob.BTC_USDT.50"]
        }))
        print("Sent subscription")
        
        self.running = True
        threading.Thread(target=self.send_ping, daemon=True).start()
        
        try:
            while True:
                message = self.ws.recv()
                if "pong" in message:
                    print(message)
        except KeyboardInterrupt:
            elapsed = datetime.now() - self.start_time
            print(f"worked: {elapsed.seconds}.{elapsed.microseconds//1000:03d} sec")
        finally:
            self.running = False
            self.ws.close()

if __name__ == "__main__":
    WebSocketLogger().run()

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions