如何用Laravel 5创建命令定期检查BitMEX WebSocket API
Let’s walk through building this Laravel command step by step—here’s a practical, battle-tested approach based on similar WebSocket integrations I’ve done:
First, generate a new Artisan command to house our WebSocket check logic:
php artisan make:command CheckBitMEXWebSocket
Open the generated file at app/Console/Commands/CheckBitMEXWebSocket.php and update the signature and description to make it clear what the command does:
protected $signature = 'bitmex:check-websocket'; protected $description = 'Periodically validate the BitMEX real-time WebSocket connection';
Laravel doesn’t include a built-in WebSocket client, so we’ll use ratchet/pawl—a robust async WebSocket client for PHP. Install it via Composer:
composer require ratchet/pawl
Now, add the core connection logic to the handle() method of your command. We’ll connect to BitMEX’s WebSocket, subscribe to a test channel (to confirm data flow), add timeout handling, and capture errors:
use Ratchet\Client\WebSocket; use React\EventLoop\Factory; use Illuminate\Support\Facades\Log; public function handle() { $loop = Factory::create(); $websocketUrl = 'wss://www.bitmex.com/realtime'; $subscribeChannel = 'instrument:XBTUSD'; // BTC/USD instrument data $timeout = 10; // 10-second timeout to avoid hanging \Ratchet\Client\connect($websocketUrl, [], [], $loop)->then(function (WebSocket $conn) use ($subscribeChannel, $loop, $timeout) { // Send a subscription request to BitMEX $conn->send(json_encode([ 'op' => 'subscribe', 'args' => [$subscribeChannel] ])); // Handle incoming messages $conn->on('message', function ($msg) use ($conn) { $data = json_decode($msg, true); $this->info('Received valid data from BitMEX: ' . substr($msg, 0, 100) . '...'); // Verify the connection is working by checking for expected data if (isset($data['table']) && $data['table'] === 'instrument') { $this->info('✅ BitMEX WebSocket connection is functional.'); Log::info('BitMEX WebSocket check passed'); $conn->close(); // Close after successful validation } }); // Handle normal connection closure $conn->on('close', function ($code = null, $reason = null) { if ($code === 1000) { $this->info('Connection closed after successful check.'); } else { $this->error("❌ Connection closed unexpectedly (code {$code}): {$reason}"); Log::error('BitMEX WebSocket closed unexpectedly', ['code' => $code, 'reason' => $reason]); } }); // Handle connection errors $conn->on('error', function (\Exception $e) use ($loop) { $this->error("❌ WebSocket error: {$e->getMessage()}"); Log::error('BitMEX WebSocket error', ['error' => $e->getMessage()]); $loop->stop(); }); // Add timeout to prevent infinite waiting $loop->addTimer($timeout, function () use ($conn) { $this->error("❌ WebSocket check timed out after {$timeout} seconds."); Log::error('BitMEX WebSocket check timed out'); $conn->close(); }); }, function (\Exception $e) use ($loop) { $this->error("❌ Failed to connect to BitMEX WebSocket: {$e->getMessage()}"); Log::error('BitMEX WebSocket connection failed', ['error' => $e->getMessage()]); $loop->stop(); }); $loop->run(); }
To run this check on a schedule, open app/Console/Kernel.php and add the command to the schedule() method. For example, to run it every 5 minutes:
protected function schedule(Schedule $schedule) { $schedule->command('bitmex:check-websocket')->everyFiveMinutes(); // Adjust frequency as needed: everyMinute(), hourly(), dailyAt('09:00'), etc. }
Don’t forget to set up the Laravel scheduler cron job on your server to trigger these scheduled tasks:
* * * * * cd /path-to-your-laravel-project && php artisan schedule:run >> /dev/null 2>&1
Configuration: Move WebSocket URL, channels, and timeout to
config/services.phpfor easy updates:// config/services.php 'bitmex' => [ 'websocket_url' => env('BITMEX_WEBSOCKET_URL', 'wss://www.bitmex.com/realtime'), 'subscribe_channels' => ['instrument:XBTUSD'], 'timeout' => env('BITMEX_WEBSOCKET_TIMEOUT', 10), ]Then reference these values in your command with
config('services.bitmex.websocket_url').Alerts: Add notifications (email, Slack, etc.) for failed checks. For example, using Laravel’s mail facade:
// Inside the error handling blocks \Illuminate\Support\Facades\Mail::to('your-alert-email@example.com')->send(new \App\Mail\BitMEXWebSocketFailure($e));Testing: Run the command manually first to validate it works:
php artisan bitmex:check-websocket
内容的提问来源于stack exchange,提问作者user3489502

