{"id":34795791,"url":"https://github.com/fcsapi/websocket-php","last_synced_at":"2026-01-13T20:45:33.458Z","repository":{"id":330540429,"uuid":"1122649458","full_name":"fcsapi/websocket-php","owner":"fcsapi","description":"PHP WebSocket client for real-time Forex, Cryptocurrency, and Stock market data streaming from FCS API - Live prices, OHLCV, Ask/Bid data with auto-reconnect.","archived":false,"fork":false,"pushed_at":"2025-12-26T11:09:52.000Z","size":19,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-12-27T18:38:30.909Z","etag":null,"topics":["crypto-price-tracking","fcsapi","realtime","stock-market","stock-prices","websocket-client"],"latest_commit_sha":null,"homepage":"https://fcsapi.com/document/socket-api","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fcsapi.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-12-25T07:50:26.000Z","updated_at":"2025-12-26T11:09:56.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/fcsapi/websocket-php","commit_stats":null,"previous_names":["fcs-developer/websocket-php"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/fcsapi/websocket-php","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fcsapi%2Fwebsocket-php","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fcsapi%2Fwebsocket-php/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fcsapi%2Fwebsocket-php/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fcsapi%2Fwebsocket-php/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fcsapi","download_url":"https://codeload.github.com/fcsapi/websocket-php/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fcsapi%2Fwebsocket-php/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28400122,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-13T14:36:09.778Z","status":"ssl_error","status_checked_at":"2026-01-13T14:35:19.697Z","response_time":56,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["crypto-price-tracking","fcsapi","realtime","stock-market","stock-prices","websocket-client"],"created_at":"2025-12-25T10:46:04.003Z","updated_at":"2026-01-13T20:45:33.452Z","avatar_url":"https://github.com/fcsapi.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# FCSAPI Realtime PHP\n\n**PHP** Real-time WebSocket client library for **Forex**, **Cryptocurrency**, and **Stock** market data from [FCS API](https://fcsapi.com).\n\nThis library provides PHP integration with WebSocket for live market data streaming. Uses the JavaScript client library for browser-based real-time updates.\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![PHP Version](https://img.shields.io/badge/PHP-%3E%3D7.4-blue.svg)](https://php.net)\n[![Packagist](https://img.shields.io/packagist/v/fcsapi/websocket.svg)](https://packagist.org/packages/fcsapi/websocket)\n\n## Features\n\n- **Real-time WebSocket** - Live price updates via WebSocket connection\n- **Multi-Market Support** - Forex, Crypto, and Stock data in one library\n- **PHP Backend Ready** - Easy integration with PHP applications\n- **Auto-Reconnect** - Handles WebSocket connection drops automatically\n- **Tab Visibility** - Smart disconnect when browser tab is hidden (saves bandwidth)\n- **Heartbeat** - Built-in WebSocket keep-alive mechanism\n\n## Demo\n\nUse demo API key for testing: `fcs_socket_demo`\n\n## Installation\n\n### Composer (Recommended)\n```bash\ncomposer require fcsapi/websocket\n```\n\n### Manual Installation\n1. Download or clone this repository\n2. Include the JavaScript library in your PHP views\n\n```php\n\u003c!-- Include JS library from CDN --\u003e\n\u003cscript src=\"https://cdn.jsdelivr.net/gh/fcsapi/websocket-php/fcs-client-lib.js\"\u003e\u003c/script\u003e\n\n\u003c!-- Or local file --\u003e\n\u003cscript src=\"\u003c?= $baseUrl ?\u003e/fcs-client-lib.js\"\u003e\u003c/script\u003e\n```\n\n## Quick Start\n\n### Basic PHP Example\n```php\n\u003c?php\n$apiKey = 'YOUR_API_KEY'; // Or use 'fcs_socket_demo' for testing\n$symbol = 'BINANCE:BTCUSDT';\n$timeframe = '1D';\n?\u003e\n\u003c!DOCTYPE html\u003e\n\u003chtml\u003e\n\u003chead\u003e\n    \u003ctitle\u003eFCS-API WebSocket Example\u003c/title\u003e\n    \u003cscript src=\"https://cdn.jsdelivr.net/gh/fcsapi/websocket-php/fcs-client-lib.js\"\u003e\u003c/script\u003e\n\u003c/head\u003e\n\u003cbody\u003e\n    \u003cdiv id=\"price\"\u003eLoading...\u003c/div\u003e\n\n    \u003cscript\u003e\n        const client = new FCSClient('\u003c?= $apiKey ?\u003e');\n\n        client.onmessage = (data) =\u003e {\n            if (data.type === 'price' \u0026\u0026 data.prices) {\n                const p = data.prices;\n                if (p.mode === 'candle' || p.mode === 'initial') {\n                    document.getElementById('price').innerText =\n                        `${data.symbol}: $${p.c} (O:${p.o} H:${p.h} L:${p.l})`;\n                }\n            }\n        };\n\n        client.connect().then(() =\u003e {\n            client.join('\u003c?= $symbol ?\u003e', '\u003c?= $timeframe ?\u003e');\n        });\n    \u003c/script\u003e\n\u003c/body\u003e\n\u003c/html\u003e\n```\n\n### Laravel Blade Example\n```php\n{{-- resources/views/realtime.blade.php --}}\n@extends('layouts.app')\n\n@section('scripts')\n\u003cscript src=\"https://cdn.jsdelivr.net/gh/fcsapi/websocket-php/fcs-client-lib.js\"\u003e\u003c/script\u003e\n@endsection\n\n@section('content')\n\u003cdiv id=\"forex-price\"\u003eLoading Forex...\u003c/div\u003e\n\u003cdiv id=\"crypto-price\"\u003eLoading Crypto...\u003c/div\u003e\n\n\u003cscript\u003e\n    const client = new FCSClient('{{ config(\"services.fcs.api_key\") }}');\n\n    client.onmessage = (data) =\u003e {\n        if (data.type === 'price' \u0026\u0026 data.prices) {\n            const p = data.prices;\n            if (p.mode === 'candle' || p.mode === 'initial') {\n                if (data.symbol.startsWith('FX:')) {\n                    document.getElementById('forex-price').innerText =\n                        `${data.symbol}: ${p.c}`;\n                } else {\n                    document.getElementById('crypto-price').innerText =\n                        `${data.symbol}: $${p.c}`;\n                }\n            }\n        }\n    };\n\n    client.connect().then(() =\u003e {\n        client.join('FX:EURUSD', '1D');\n        client.join('BINANCE:BTCUSDT', '1D');\n    });\n\u003c/script\u003e\n@endsection\n```\n\n### CodeIgniter Example\n```php\n\u003c?php\n// app/Controllers/Realtime.php\nnamespace App\\Controllers;\n\nclass Realtime extends BaseController\n{\n    public function index()\n    {\n        $data = [\n            'apiKey' =\u003e getenv('FCS_API_KEY') ?: 'fcs_socket_demo',\n            'symbols' =\u003e ['FX:EURUSD', 'FX:GBPUSD', 'BINANCE:BTCUSDT']\n        ];\n        return view('realtime', $data);\n    }\n}\n```\n\n```php\n\u003c!-- app/Views/realtime.php --\u003e\n\u003c!DOCTYPE html\u003e\n\u003chtml\u003e\n\u003chead\u003e\n    \u003ctitle\u003eReal-time Prices\u003c/title\u003e\n    \u003cscript src=\"https://cdn.jsdelivr.net/gh/fcsapi/websocket-php/fcs-client-lib.js\"\u003e\u003c/script\u003e\n\u003c/head\u003e\n\u003cbody\u003e\n    \u003ctable id=\"prices\"\u003e\n        \u003cthead\u003e\n            \u003ctr\u003e\n                \u003cth\u003eSymbol\u003c/th\u003e\n                \u003cth\u003eOpen\u003c/th\u003e\n                \u003cth\u003eHigh\u003c/th\u003e\n                \u003cth\u003eLow\u003c/th\u003e\n                \u003cth\u003eClose\u003c/th\u003e\n                \u003cth\u003eVolume\u003c/th\u003e\n            \u003c/tr\u003e\n        \u003c/thead\u003e\n        \u003ctbody\u003e\u003c/tbody\u003e\n    \u003c/table\u003e\n\n    \u003cscript\u003e\n        const client = new FCSClient('\u003c?= esc($apiKey) ?\u003e');\n        const symbols = \u003c?= json_encode($symbols) ?\u003e;\n\n        client.onmessage = (data) =\u003e {\n            if (data.type === 'price' \u0026\u0026 data.prices) {\n                updatePriceRow(data.symbol, data.prices);\n            }\n        };\n\n        function updatePriceRow(symbol, p) {\n            if (p.mode !== 'candle' \u0026\u0026 p.mode !== 'initial') return;\n\n            let row = document.getElementById('row-' + symbol.replace(':', '-'));\n            if (!row) {\n                row = document.createElement('tr');\n                row.id = 'row-' + symbol.replace(':', '-');\n                document.querySelector('#prices tbody').appendChild(row);\n            }\n            row.innerHTML = `\n                \u003ctd\u003e${symbol}\u003c/td\u003e\n                \u003ctd\u003e${p.o}\u003c/td\u003e\n                \u003ctd\u003e${p.h}\u003c/td\u003e\n                \u003ctd\u003e${p.l}\u003c/td\u003e\n                \u003ctd\u003e${p.c}\u003c/td\u003e\n                \u003ctd\u003e${p.v || '-'}\u003c/td\u003e\n            `;\n        }\n\n        client.connect().then(() =\u003e {\n            symbols.forEach(s =\u003e client.join(s, '1D'));\n        });\n    \u003c/script\u003e\n\u003c/body\u003e\n\u003c/html\u003e\n```\n\n## API Reference\n\n### JavaScript Client (Browser-side)\n\n#### Constructor\n```javascript\nconst client = new FCSClient(apiKey, url);\n```\n| Parameter | Type | Default | Description |\n|-----------|------|---------|-------------|\n| `apiKey` | string | required | Your FCS API key |\n| `url` | string | `wss://ws-v4.fcsapi.com/ws` | WebSocket server URL (optional) |\n\n### Methods\n\n#### `connect()`\nConnects to the WebSocket server. Returns a Promise.\n```javascript\nclient.connect().then(() =\u003e {\n    console.log('Connected!');\n}).catch(err =\u003e {\n    console.error('Connection failed:', err);\n});\n```\n\n#### `disconnect()`\nManually closes the connection.\n```javascript\nclient.disconnect();\n```\n\n#### `join(symbol, timeframe)`\nSubscribe to a symbol for real-time updates.\n```javascript\n// Forex\nclient.join('FX:EURUSD', '1m');\n\n// Crypto\nclient.join('BINANCE:BTCUSDT', '1m');\n\n// Stock\nclient.join('NASDAQ:AAPL', '1m');\n```\n\n#### `leave(symbol, timeframe)`\nUnsubscribe from a symbol.\n```javascript\nclient.leave('FX:EURUSD', '1m');\n```\n\n#### `removeAll()`\nUnsubscribe from all symbols.\n```javascript\nclient.removeAll();\n```\n\n### Event Callbacks\n\n| Callback | Description |\n|----------|-------------|\n| `onconnected` | Fired when connection is established |\n| `onmessage` | Fired when data is received |\n| `onclose` | Fired when connection is closed |\n| `onerror` | Fired when an error occurs |\n| `onreconnect` | Fired when reconnection is successful |\n\n```javascript\nclient.onconnected = () =\u003e console.log('Connected!');\nclient.onmessage = (data) =\u003e console.log('Data:', data);\nclient.onclose = (event) =\u003e console.log('Closed:', event.code);\nclient.onerror = (err) =\u003e console.error('Error:', err);\nclient.onreconnect = () =\u003e console.log('Reconnected!');\n```\n\n### Configuration Options\n\n| Property | Type | Default | Description |\n|----------|------|---------|-------------|\n| `reconnectDelay` | number | 3000 | Delay (ms) before reconnection attempt |\n| `reconnectlimit` | number | 5 | Maximum reconnection attempts |\n| `focusTimeout` | number | 3 | Minutes before disconnect when tab is hidden (0 = never) |\n\n```javascript\nconst client = new FCSClient('YOUR_API_KEY');\nclient.reconnectDelay = 5000;  // 5 seconds\nclient.reconnectlimit = 10;    // 10 attempts\nclient.focusTimeout = 5;       // 5 minutes\n```\n\n### Message Data Format\n\nThe WebSocket sends different message types:\n\n#### 1. Join Confirmation\n```javascript\n{\n    \"type\": \"message\",\n    \"success\": true,\n    \"message\": \"Successfully joined room: BINANCE:BTCUSDT_1D_0s\",\n    \"room\": \"BINANCE:BTCUSDT_1D_0s\",\n    \"symbol\": \"BTCUSDT\",\n    \"timeframe\": \"1D\",\n    \"short\": \"joined_room\"\n}\n```\n\n#### 2. Profile Data (One-time on join)\n```javascript\n{\n    \"type\": \"price\",\n    \"symbol\": \"BINANCE:BTCUSDT\",\n    \"timeframe\": \"1D\",\n    \"prices\": {\n        \"mode\": \"profile\",\n        \"profile\": {\n            \"current_session\": \"market\",\n            \"timezone\": \"Etc/UTC\",\n            \"pro_name\": \"BINANCE:BTCUSDT\",\n            \"update_mode\": \"streaming\"\n        }\n    }\n}\n```\n\n#### 3. Initial Candle Data (One-time on join)\n```javascript\n{\n    \"type\": \"price\",\n    \"symbol\": \"BINANCE:BTCUSDT\",\n    \"timeframe\": \"1D\",\n    \"prices\": {\n        \"mode\": \"initial\",\n        \"t\": 1766361600,      // Timestamp (Unix seconds)\n        \"o\": 88658.87,        // Open price\n        \"h\": 90588.23,        // High price\n        \"l\": 87900,           // Low price\n        \"c\": 89962.61,        // Close price\n        \"v\": 0.247            // Volume\n    }\n}\n```\n\n#### 4. Live Candle Updates (Continuous)\nPrimary update mode - contains all price data including OHLCV and Ask/Bid.\n```javascript\n{\n    \"type\": \"price\",\n    \"symbol\": \"BINANCE:BTCUSDT\",\n    \"timeframe\": \"1D\",\n    \"prices\": {\n        \"mode\": \"candle\",\n        \"t\": 1766361600,      // Timestamp\n        \"o\": 88658.87,        // Open\n        \"h\": 90588.23,        // High\n        \"l\": 87900,           // Low\n        \"c\": 89962.61,        // Close\n        \"v\": 8192.70,         // Volume\n        \"a\": 89962.62,        // Ask price\n        \"b\": 89962.61         // Bid price\n    }\n}\n```\n\n#### 5. Ask/Bid Updates\nSent when only Ask/Bid data changes. All values in this message are updated.\n```javascript\n{\n    \"type\": \"price\",\n    \"symbol\": \"BINANCE:BTCUSDT\",\n    \"timeframe\": \"1D\",\n    \"prices\": {\n        \"mode\": \"askbid\",\n        \"update\": 1766411426, // Update timestamp\n        \"c\": 89962.61,        // Close price\n        \"a\": 89962.62,        // Ask price\n        \"b\": 89962.61,        // Bid price\n        \"t\": 1766361600       // Candle timestamp\n    }\n}\n```\n\n### Handling Different Price Modes\n\n```javascript\nclient.onmessage = (data) =\u003e {\n    if (data.type === 'price' \u0026\u0026 data.prices) {\n        const p = data.prices;\n        const symbol = data.symbol;\n\n        switch (p.mode) {\n            case 'profile':\n                console.log(`${symbol} Profile loaded`);\n                break;\n\n            case 'initial':\n            case 'candle':\n                console.log(`${symbol}: O=${p.o} H=${p.h} L=${p.l} C=${p.c} V=${p.v} Ask=${p.a} Bid=${p.b}`);\n                break;\n\n            case 'askbid':\n                console.log(`${symbol}: Ask=${p.a} Bid=${p.b}`);\n                break;\n        }\n    }\n};\n```\n\n## Symbol Format\n\nSymbols must include an exchange prefix:\n\n| Market | Format | Examples |\n|--------|--------|----------|\n| Forex | `FX:PAIR` | `FX:EURUSD`, `FX:GBPUSD`, `FX:USDJPY` |\n| Crypto | `EXCHANGE:PAIR` | `BINANCE:BTCUSDT`, `BINANCE:ETHUSDT` |\n| Stock | `EXCHANGE:SYMBOL` | `NASDAQ:AAPL`, `NYSE:TSLA` |\n\n## Timeframes\n\n| Timeframe | Description |\n|-----------|-------------|\n| `1` | 1 minute |\n| `5` | 5 minutes |\n| `15` | 15 minutes |\n| `30` | 30 minutes |\n| `1H` | 1 hour |\n| `4H` | 4 hours |\n| `1D` | 1 day |\n| `1W` | 1 week |\n| `1M` | 1 month |\n\n## Examples\n\nCheck the `/examples` folder for complete working demos:\n\n- [forex-example.php](examples/forex-example.php) - Real-time Forex prices\n- [crypto-example.php](examples/crypto-example.php) - Real-time Cryptocurrency prices\n- [stock-example.php](examples/stock-example.php) - Real-time Stock prices\n\n## PHP Framework Integration\n\n### Laravel\nAdd to your `.env`:\n```\nFCS_API_KEY=your_api_key_here\n```\n\nAdd to `config/services.php`:\n```php\n'fcs' =\u003e [\n    'api_key' =\u003e env('FCS_API_KEY', 'fcs_socket_demo'),\n],\n```\n\n### CodeIgniter 4\nAdd to your `.env`:\n```\nFCS_API_KEY=your_api_key_here\n```\n\n### Symfony\nAdd to your `.env`:\n```\nFCS_API_KEY=your_api_key_here\n```\n\n## Browser Tab Visibility\n\nThe library automatically handles browser tab visibility to save bandwidth:\n\n- When tab is hidden for more than 3 minutes (configurable), connection is closed\n- When tab becomes visible again, connection is automatically restored\n- All subscriptions are automatically rejoined after reconnection\n\nSet `focusTimeout = 0` to disable this feature:\n```javascript\nclient.focusTimeout = 0; // Never disconnect when tab hidden\n```\n\n## Error Handling\n\n```javascript\nclient.onerror = (err) =\u003e {\n    console.error('WebSocket error:', err);\n};\n\nclient.onclose = (event) =\u003e {\n    if (event.code !== 1000) {\n        console.error('Unexpected close:', event.code, event.reason);\n    }\n};\n```\n\n## Get API Key\n\n1. Visit [FCS API](https://fcsapi.com)\n2. Sign up for a free account\n3. Get your API key from the dashboard\n\n## Documentation\n\nFor complete API documentation, visit:\n- [FCS API Documentation](https://fcsapi.com/document/stock-api)\n- [WebSocket API Guide](https://fcsapi.com/document/stock-api#websocket)\n\n## Support\n\n- Email: support@fcsapi.com\n- Website: [fcsapi.com](https://fcsapi.com)\n\n## License\n\nMIT License - see [LICENSE](LICENSE) file for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffcsapi%2Fwebsocket-php","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffcsapi%2Fwebsocket-php","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffcsapi%2Fwebsocket-php/lists"}