WebSocket соединение с Binance — это фундаментальный навык для работы с данными в реальном времени. В этом руководстве я подробно объясню, как реализовать надёжную стратегию переподключения, которая будет работать стабильно даже при проблемах с сетью.

このガイドでは、HolySheep AIを活用した効率的な実装方法を、プログラミングが初めてという方に向けてゼロから丁寧に解説します。

WebSocket 再接続とは?超わかる基礎解説

まず「WebSocket 再接続」が何かを、たとえ話で説明します。

LINEの電話にたとえてみよう

LINEで音声通話をしている姿を想像してください。あなたが「Sさん」と通话中、突然Wi-Fiが切れました。どうしますか?

WebSocket 再接続戦略とは、まさにこの「自動で再接続する仕組み」です。サーバーの данные があなたのプログラムに届かなくなったとき、自動的に再接続を試みる機能のことです。

なぜ再接続が重要なのか

Binanceの取引データをリアルタイムで取得している場合、以下の状況で接続が切れます:

再接続の仕組みがなければ、接続が切れた時点でデータの受信が完全に停止します。これはトレーディングボットにとって致命的な问题です。

HolySheep AIを選ぶ理由

API連携を学ぶなら、HolySheep AIは最適な选择です:

項目HolySheep AI他社比較
レート¥1=$1(85%節約)公式比3倍高昂
対応決済WeChat Pay/Alipay/カードカードのみ
レイテンシ<50ms100-200ms
無料クレジット登録で即时付与なし
DeepSeek V3.2$0.42/MTok$2+

特に初心者にとって學習用のコストが低いことは非常に重要です。Mistakesしても 걱정する必要がありません。

ステップ1:Binance WebSocketの기본構造を理解する

まず、Binance公式のWebSocket接続の 기본構造を見てみましょう。以下の点是、超重要なので必ず覚えておいてください:

Binance WebSocket URL

# Binance公式WebSocket接続URL
WSS_URL = "wss://stream.binance.com:9443/ws"

ティッカー情報を受信する場合のストリーム名

STREAM_NAME = "btcusdt@ticker" FULL_URL = f"{WSS_URL}/{STREAM_NAME}"

結果: wss://stream.binance.com:9443/ws/btcusdt@ticker

ポイント:「wss://」は通常の「https://」のWebSocket版です。9443はWebSocket专用のポート番号です。

最简单的WebSocketクライアント(動作確認用)

import websocket
import json

def on_message(ws, message):
    """メッセージ受信時に呼び出される関数"""
    data = json.loads(message)
    # BTC/USDTの価格变动を表示
    if 's' in data and data['s'] == 'BTCUSDT':
        price = float(data['c'])  # 現在価格
        change = float(data['P'])  # 変動率(%)
        print(f"BTC/USDT: ${price:,.2f} ({change:+.2f}%)")

def on_error(ws, error):
    """エラー発生時に呼び出される関数"""
    print(f"エラー発生: {error}")

def on_close(ws, close_code, close_msg):
    """接続切断時に呼び出される関数"""
    print(f"接続切断: コード={close_code}, 理由={close_msg}")

def on_open(ws):
    """接続開始時に呼び出される関数"""
    print("=== Binanceに接続しました ===")

WebSocketアプリ 생성

ws = websocket.WebSocketApp( FULL_URL, on_message=on_message, on_error=on_error, on_close=on_close, on_open=on_open )

接続維持( 무한ループ)

ws.run_forever(ping_interval=30)

スクリーンショットイメージ:このコードを実行すると、ターミナルに1秒ごとにBTC/USDTの価格と変動率が如下のように表示されます:

=== Binanceに接続しました ===
BTC/USDT: $67,234.50 (+1.23%)
BTC/USDT: $67,238.90 (+1.25%)
BTC/USDT: $67,231.20 (+1.22%)
^C  # Ctrl+Cで停止

ステップ2:基本的な再接続戦略を実装する

さて、ここから本題です。接続が切れたときに 자동으로 再接続する仕組みを実装しましょう。

傻瓜式再接続マネージャー

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

class BinanceReconnectManager:
    """Binance WebSocket 再接続マネージャー"""
    
    def __init__(self, symbol="btcusdt", stream_type="ticker"):
        self.symbol = symbol.lower()
        self.stream_type = stream_type
        self.ws = None
        self.is_running = False
        
        # 再接続設定
        self.max_retries = 10          # 最大再試行回数
        self.base_delay = 1             # 初期待機秒数
        self.max_delay = 60            # 最大待機秒数
        self.current_retry = 0          # 現在の試行回数
        
        # 成功した接続回数(統計用)
        self.connection_count = 0
        
    def get_url(self):
        """接続URLを生成"""
        stream_name = f"{self.symbol}@{self.stream_type}"
        return f"wss://stream.binance.com:9443/ws/{stream_name}"
    
    def on_message(self, ws, message):
        """メッセージ受信処理"""
        try:
            data = json.loads(message)
            self.connection_count += 1
            
            # BTC/USDT価格を表示
            if 's' in data:
                symbol = data['s']
                price = float(data['c'])
                change = float(data['P'])
                print(f"[{datetime.now().strftime('%H:%M:%S')}] "
                      f"{symbol}: ${price:,.2f} ({change:+.2f}%) | "
                      f"接続#{self.connection_count}")
                      
        except Exception as e:
            print(f"メッセージ解析エラー: {e}")
    
    def on_error(self, ws, error):
        """エラー処理"""
        print(f"[エラー] {error}")
    
    def on_close(self, ws, close_code, close_msg):
        """切断時の処理"""
        print(f"[切断] コード: {close_code}, 理由: {close_msg}")
        self.is_running = False
    
    def on_open(self, ws):
        """接続成功時の処理"""
        print(f"[接続] Binance WebSocket接続成功!")
        self.current_retry = 0  # 試行回数をリセット
        self.is_running = True
    
    def calculate_delay(self):
        """指数バックオフで待機時間を計算"""
        delay = min(self.base_delay * (2 ** self.current_retry), self.max_delay)
        # 随机 jitter(0.5〜1.5倍)を追加して同時接続を分散
        import random
        delay *= (0.5 + random.random())
        return delay
    
    def run_with_reconnect(self):
        """再接続功能付きの実行"""
        print("=== Binance WebSocket 再接続システム 起動 ===")
        
        while self.current_retry < self.max_retries:
            try:
                url = self.get_url()
                print(f"\n[試行 {self.current_retry + 1}/{self.max_retries}] "
                      f"{url} に接続中...")
                
                self.ws = websocket.WebSocketApp(
                    url,
                    on_message=self.on_message,
                    on_error=self.on_error,
                    on_close=self.on_close,
                    on_open=self.on_open
                )
                
                # ping_interval: この秒数ごとに生存確認を送信
                self.ws.run_forever(ping_interval=30)
                
                # 切断後の処理
                if self.is_running:
                    break  # 正常終了の場合はループを抜ける
                    
            except Exception as e:
                print(f"[例外] {e}")
            
            # 再接続前的待機
            self.current_retry += 1
            if self.current_retry < self.max_retries:
                delay = self.calculate_delay()
                print(f"[待機] {delay:.1f}秒後に再接続します...")
                time.sleep(delay)
        
        print(f"\n=== 最大試行回数に達しました ===")
        print(f"合計接続回数: {self.connection_count}")

使用例

if __name__ == "__main__": manager = BinanceReconnectManager(symbol="ethusdt", stream_type="ticker") manager.run_with_reconnect()

実行结果の例:

=== Binance WebSocket 再接続システム 起動 ===

[試行 1/10] wss://stream.binance.com:9443/ws/ethusdt@ticker に接続中...
[接続] Binance WebSocket接続成功!
[12:34:56] ETHUSDT: $3,456.78 (+2.34%) | 接続#1
[12:34:57] ETHUSDT: $3,457.12 (+2.35%) | 接続#2
...
[切断] コード: 1006, 理由: 
[待機] 1.3秒後に再接続します...

[試行 2/10] wss://stream.binance.com:9443/ws/ethusdt@ticker に接続中...
[接続] Binance WebSocket接続成功!
[12:35:02] ETHUSDT: $3,458.90 (+2.38%) | 接続#3

ステップ3:応用——複数ストリームと高度な再接続

実際のトレーディングボットでは、複数の通貨ペアや不同种类的データを同時に受信する必要があります。ここでは进阶版の管理器を 소개합니다。

マルチストリーム対応・高级再接続マネージャー

import websocket
import json
import time
import threading
import random
from datetime import datetime
from collections import deque
from enum import Enum

class ConnectionState(Enum):
    """接続状態枚举"""
    DISCONNECTED = 0
    CONNECTING = 1
    CONNECTED = 2
    RECONNECTING = 3

class AdvancedBinanceManager:
    """高度再接続機能付きBinanceマネージャー"""
    
    def __init__(self):
        # 接続状態管理
        self.state = ConnectionState.DISCONNECTED
        self.ws = None
        self.main_thread = None
        
        # 設定パラメータ
        self.max_retries = 20           # 最大再試行回数(增加)
        self.base_delay = 1             # 基础待機秒数
        self.max_delay = 120            # 最大待機秒数(2分)
        self.retry_count = 0
        
        # 订阅ストリーム設定
        self.streams = [
            "btcusdt@ticker",
            "ethusdt@ticker", 
            "bnbusdt@ticker",
            "btcusdt@kline_1m"  # 1分足ローソク足
        ]
        
        # データ蓄積用
        self.price_history = deque(maxlen=100)  # 最新100件保持
        self.last_message_time = None
        self.connection_start_time = None
        
        # 統計
        self.total_messages = 0
        self.reconnect_count = 0
        self.uptime_seconds = 0
        
    def create_combined_url(self):
        """複数ストリームを組み合わせたURLを生成"""
        streams = "/".join(self.streams)
        return f"wss://stream.binance.com:9443/stream?streams={streams}"
    
    def process_ticker_data(self, data):
        """ティッカーデータ処理"""
        symbol = data.get('s', 'UNKNOWN')
        price = float(data.get('c', 0))
        change = float(data.get('P', 0))
        volume = float(data.get('v', 0))
        
        self.total_messages += 1
        self.last_message_time = datetime.now()
        
        # 価格履歴に追加
        self.price_history.append({
            'time': self.last_message_time,
            'symbol': symbol,
            'price': price,
            'change': change
        })
        
        # 表示(每秒1回程度に制限)
        print(f"[{self.last_message_time.strftime('%H:%M:%S')}] "
              f"{symbol}: ${price:,.2f} ({change:+.2f}%)")
    
    def process_kline_data(self, data):
        """ローソク足データ処理"""
        kline = data.get('k', {})
        symbol = kline.get('s', 'UNKNOWN')
        open_price = float(kline.get('o', 0))
        high_price = float(kline.get('h', 0))
        low_price = float(kline.get('l', 0))
        close_price = float(kline.get('c', 0))
        
        self.total_messages += 1
        
        print(f"[KLINE {symbol}] O:${open_price:.2f} H:${high_price:.2f} "
              f"L:${low_price:.2f} C:${close_price:.2f}")
    
    def on_message(self, ws, message):
        """ 메시지 수신 처리 """
        try:
            wrapper = json.loads(message)
            stream = wrapper.get('stream', '')
            data = wrapper.get('data', {})
            
            if '@ticker' in stream:
                self.process_ticker_data(data)
            elif '@kline' in stream:
                self.process_kline_data(data)
                
        except Exception as e:
            print(f"[解析エラー] {e}")
    
    def on_error(self, ws, error):
        """ エラー処理 """
        print(f"[エラー] {error}")
        self.state = ConnectionState.RECONNECTING
    
    def on_close(self, ws, code, msg):
        """ 切断処理 """
        end_time = datetime.now()
        if self.connection_start_time:
            duration = (end_time - self.connection_start_time).total_seconds()
            print(f"[切断] 継続時間: {duration:.1f}秒 | "
                  f"メッセージ数: {self.total_messages}")
        self.state = ConnectionState.DISCONNECTED
    
    def on_open(self, ws):
        """ 接続成功 """
        self.state = ConnectionState.CONNECTED
        self.connection_start_time = datetime.now()
        self.retry_count = 0
        print(f"[接続] {len(self.streams)}ストリーム購読開始")
    
    def calculate_backoff_delay(self):
        """指数バックオフ+ジッター計算"""
        # 指数バックオフ: 1, 2, 4, 8, 16...秒
        delay = min(self.base_delay * (2 ** self.retry_count), self.max_delay)
        # ジッター: ±50%
        jitter = delay * (0.5 + random.random())
        return jitter
    
    def should_reconnect(self):
        """再接続すべきか判定"""
        if self.retry_count >= self.max_retries:
            return False
        return True
    
    def health_check(self):
        """接続健全性チェック(別スレッドで実行)"""
        while self.state in [ConnectionState.CONNECTED, ConnectionState.RECONNECTING]:
            time.sleep(10)  # 10秒ごとにチェック
            
            if self.last_message_time:
                gap = (datetime.now() - self.last_message_time).total_seconds()
                if gap > 60:  # 60秒以上メッセージなし
                    print(f"[警告] {gap:.1f}秒間メッセージなし。再接続を検討...")
                    
            # 稼働時間表示
            if self.connection_start_time:
                uptime = (datetime.now() - self.connection_start_time).total_seconds()
                print(f"[稼働] 経過時間: {uptime:.0f}秒 | "
                      f"メッセージ: {self.total_messages} | "
                      f"再接続回数: {self.reconnect_count}")
    
    def run(self):
        """メイン実行メソッド"""
        print("=" * 60)
        print("Binance 高度再接続システム")
        print("=" * 60)
        
        # 健全性チェックスレッド起動
        health_thread = threading.Thread(target=self.health_check, daemon=True)
        health_thread.start()
        
        while self.should_reconnect():
            try:
                self.state = ConnectionState.CONNECTING
                url = self.create_combined_url()
                
                print(f"\n[試行 {self.retry_count + 1}/{self.max_retries}]")
                print(f"URL: {url[:80]}...")
                
                self.ws = websocket.WebSocketApp(
                    url,
                    on_message=self.on_message,
                    on_error=self.on_error,
                    on_close=self.on_close,
                    on_open=self.on_open
                )
                
                # 接続維持
                self.ws.run_forever(ping_interval=30, ping_timeout=10)
                
                # 正常終了チェック
                if self.state == ConnectionState.CONNECTED:
                    break
                    
            except Exception as e:
                print(f"[例外] {e}")
            
            # 再接続処理
            self.retry_count += 1
            self.reconnect_count += 1
            self.state = ConnectionState.RECONNECTING
            
            if self.should_reconnect():
                delay = self.calculate_backoff_delay()
                print(f"[待機] {delay:.1f}秒後に再接続...")
                time.sleep(delay)
        
        print("\n" + "=" * 60)
        print("システム終了")
        print(f"合計再接続回数: {self.reconnect_count}")
        print(f"合計メッセージ数: {self.total_messages}")
        print("=" * 60)

使用例

if __name__ == "__main__": manager = AdvancedBinanceManager() manager.run()

スクリーンショットポイント:실행 결과, 아래처럼 여러 통화对的의 실시간 데이터가 함께 표시됩니다:

============================================================
Binance 高度再接続システム
============================================================

[試行 1/20]
URL: wss://stream.binance.com:9443/stream?streams=btcusdt@ticker...
[接続] 4ストリーム購読開始
[12:34:56] BTCUSDT: $67,234.50 (+1.23%)
[12:34:56] ETHUSDT: $3,456.78 (+2.34%)
[12:34:56] BNBUSDT: $567.23 (-0.45%)
[KLINE BTCUSDT] O:$67,200.00 H:$67,300.00 L:$67,100.00 C:$67,234.50
[稼働] 経過時間: 10秒 | メッセージ: 24 | 再接続回数: 0
[稼働] 経過時間: 20秒 | メッセージ: 48 | 再接続回数: 0
...

向いている人・向いていない人

向いている人向いていない人
暗号通貨の自动取引 botを作成したい人 WebSocket基础知识を一から极为的に学びたい人
リアルタイムで価格データを取得したい人 高頻度取引(HFT)所需的超低遅延環境が必要な人
API連携の基本をarians実践的に学びたい人 Binance以外的取引所專门的に使いたい人
Pythonでのネットワークプログラミング経験がある人 他のプログラム言語(Node.js等)を优先したい人

価格とROI

この再接続戦略の実装を学ぶことは、以下の面で投資対効果が高いです:

投資項目コストManfaat
学習時間(このガイド)約2〜3時間WebSocketの深い理解
API利用料(Binance)無料リアルタイムデータ受信
API利用料(分析用AI)DeepSeek V3.2 ¥0.42/MTokパターン分析・予測
開発環境無料(Python basic libraries)本格的なbot開発基盤

HolySheep AIなら、注册後に免费クレジットがもらえるため、実际にコードを试しながら学ぶことができます。

HolySheep AIを選ぶ理由

我再接続戦略の実装实验中、HolySheep AIは以下の点で非常に 도움이りました:

よくあるエラーと対処法

エラー1:ConnectionResetError (104) — リセットされ続けた

# 错误内容
ConnectionResetError: [WinError 104] 接続が相手側からリセットされました

原因

サーバー侧の负荷过高、または一分钟あたりの接続上限超え

解決策

1. 再接続间隔を伸ばす self.max_delay = 300 # 最大5分待機 2. 接続数を制限( 동시에多个接続しない)

例:5秒間隔で别々の通貨に接続

time.sleep(5) 3. 公式の接続制限を確認

https://developers.binance.com/docs/websocket-api/connection-limits

エラー2:websocket._exceptions.WebSocketTimeoutException

# 错误内容
websocket._exceptions.WebSocketTimeoutException: ping timed out

原因

ping/pong(生存確認)のやり取りがタイムアウトした

解決策

1. ping_timeout 设置过长 self.ws.run_forever( ping_interval=30, ping_timeout=20 # タイムアウト延长(デフォルト10秒) ) 2. ネットワーク状况を確認 import subprocess result = subprocess.run(['ping', '-n', '3', 'stream.binance.com'], capture_output=True, text=True) print(result.stdout) 3. 代替接続先を試す

アジア向けエンドポイント

ASIA_WSS = "wss://stream.binance.com:9443/ws"

米国向けエンドポイント

US_WSS = "wss://stream.binance.us:9443/ws"

エラー3:JSON解析エラー — データが突然変わる

# 错误内容
json.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

原因

1. 空のメッセージを受信した 2. WebSocketがHTTP錯誤ページを返した 3. 接続URLが間違っている

解決策

1. 空メッセージチェックを追加 def on_message(self, ws, message): if not message or not message.strip(): print("[警告] 空メッセージを受信") return # 続きの処理... 2. URL 完全性チェック def get_url(self): symbol = self.symbol.lower() # 小文字+先頭一致的确认 assert symbol.islower(), "Symbol must be lowercase" assert len(symbol) >= 6, "Invalid symbol length" return f"wss://stream.binance.com:9443/ws/{symbol}@ticker" 3. HTTP错误対応 try: data = json.loads(message) except json.JSONDecodeError: print(f"[エラー] 解析不可: {message[:100]}")

エラー4:OutOfMemory — 長時間稼働でメモリリーク

# 错误内容
MemoryError: Unable to allocate array...

原因

1. price_history 等是无制限にデータが溜まる 2. WebSocketメッセージの处理 incompleto

解決策

1. deque の maxlen を設定(既に実装済みだが确认) self.price_history = deque(maxlen=1000) # 上限设定 2. 一定间隔で明示的にクリア def clear_old_data(self): if len(self.price_history) > 1000: # 古いデータをファイルに保存してからクリア self.save_to_file() self.price_history.clear() 3. 定期的メモリチェック import psutil import os def log_memory(): process = psutil.Process(os.getpid()) mem_mb = process.memory_info().rss / 1024 / 1024 print(f"[メモリ] 使用量: {mem_mb:.1f} MB")

まとめ:実装チェックリスト

最後に、このガイドで学んだことを確認用的チェックリストです:

次のステップ

この再接続戦略掌握了したら、以下のような応用に挑戦해보세요:

HolySheep AIなら、API利用料が¥1=$1という破格のレートで、注册者には免费クレジットが付与されます。學習用途であれば十分试験できますので、ぜひこの机会に注册してみてください。


👉 HolySheep AI に登録して無料クレジットを獲得

※ 本記事の情報は2024年時点のものです。最新情報はBinance公式ドキュメントをご確認ください。