# WebSocket Abonelikleri

> Source: https://docs.blockvectra.com/tr/guides/websocket-subscriptions/

BlockVectra, standart JSON-RPC isteklerinin yanı sıra gerçek zamanlı Ethereum olay abonelikleri akışı için güvenli WebSocket bağlantıları (`wss://`) sağlar.

## WebSocket, Webhook veya yoklama arasında seçim yapma

Uygulamanız bir bağlantıyı canlı tutabildiğinde gerçek zamanlı `newHeads` ve filtrelenmiş `logs` için WebSocket kullanın. İzlenen cüzdan etkinliğini bir HTTPS uç noktasında [ham gövde imza doğrulaması](https://docs.blockvectra.com/tr/guides/webhook-push/#verify-signatures), yeniden denemeler ve saklanan eşleşmelerin yeniden oynatılmasıyla (replay) almak için [Blockchain Webhook API'sini](https://docs.blockvectra.com/tr/guides/webhook-push/) kullanın. Zamanlanmış ERC-20 ödeme takibi ve geçmiş logları geriye dönük doldurma için [HTTP yoklamasını](https://docs.blockvectra.com/tr/guides/stablecoin-payments/) kullanın. Stablecoin rehberi ayrıca bir [USDT / USDC Webhook alıcısını](https://docs.blockvectra.com/tr/guides/stablecoin-payments/#receive-payments-with-webhooks) gösterir. Geliştiriciler ve AI Agent'lar için zincir desteği, alıcı gereksinimleri ve kurtarma dengeleri genelinde mimari bir karşılaştırma için [Webhooks, WebSocket veya RPC yoklama seçme rehberine](https://docs.blockvectra.com/tr/guides/webhook-vs-websocket/) bakın.

WebSocket desteği `GET /v1/chains` içindeki `ws` ve `subscriptions` alanlarından gelir; Push desteği ise kimliği doğrulanmış `GET /v1/push/chains` listesinden gelir. WebSocket desteği olmayan bir zincir, bu listede yer alıyorsa yine de adres Webhook'larını kullanabilir.

WebSocket bağlantı kesilmeleri yeniden abone olmayı ve geriye dönük doldurmayı gerektirir; Push kontrol olayları olan `subscription.gap` veya `chain.reorg` olaylarını yayınlamazlar. Webhook'lar için bir boşluk aralık taraması gerektirir; bir reorg bildirimi, otomatik olarak yeniden iletilen kanonik olayları saklamadan önce değiştirilen olayların işaretlenmesini veya atılmasını gerektirir. [Push yeniden oynatma (replay)](https://docs.blockvectra.com/tr/guides/webhook-push/#delivery-retries-and-replay), bir adres veya zincir eklenmeden önceki ya da abonelik çevrimdışıyken gerçekleşen verileri değil, saklanan eşleşmeleri yeniden gönderir. Kurtarmayı uygularken [faturalandırma kurallarını](https://docs.blockvectra.com/tr/guides/billing-rules/) ve [hata referansını](https://docs.blockvectra.com/tr/errors/) inceleyin.

## Kullanılabilir zincirler

`GET /v1/chains` içinde `ws` (boolean) ve `subscriptions` (desteklenen türlerin dizisi) alanlarını okuyarak bir ağda WebSocket aboneliklerinin etkin olup olmadığını kontrol edebilirsiniz.

Aşağıdaki tablo, WebSocket desteğinin etkin olduğu ağları yansıtmaktadır:

| Zincir | WebSocket Uç Noktası (Yol Anahtarı) |
| --- | --- |
| Robinhood Chain | `wss://api.blockvectra.com/v1/robinhood_mainnet/{api_key}` |
| Robinhood Chain Testnet | `wss://api.blockvectra.com/v1/robinhood_testnet/{api_key}` |

## Bağlantı ve kimlik doğrulama

İstemciler güvenli bir TLS WebSocket bağlantısı (`wss://`) kurar. API key iki şekilde sağlanabilir:

* **Yol anahtarı (Path key)**: `wss://api.blockvectra.com/v1/{chain}/{api_key}`
* **Başlık anahtarı (Header key)**: HTTP Upgrade el sıkışması sırasında `x-api-key: {api_key}` veya `Authorization: Bearer {api_key}` başlığı ile `wss://api.blockvectra.com/v1/{chain}`.

Bir yol anahtarı ile yol anahtarı kullanılır ve her iki kimlik doğrulama başlığı da yoksayılır. Bir yol anahtarı olmadığında, boş olmayan bir `x-api-key` başlığı `Authorization: Bearer` başlığına göre önceliklidir. Tarayıcı WebSocket API'leri bu başlıkları ayarlayamaz; yol anahtarlı URL'yi kullanın.

### El sıkışma (handshake) kabul kontrolleri

El sıkışma şu nedenlerle başarısız olabilir:

* **Kimlik doğrulama**: Bulunmayan bir API key HTTP 401 ([`missing_api_key`](https://docs.blockvectra.com/tr/errors/#missing_api_key)) döndürür; bilinmeyen, devre dışı bırakılmış veya iptal edilmiş bir API key HTTP 401 ([`invalid_api_key`](https://docs.blockvectra.com/tr/errors/#invalid_api_key)) döndürür; kimlik doğrulama geçici olarak kullanılamıyorsa yanıt HTTP 503 ([`auth_unavailable`](https://docs.blockvectra.com/tr/errors/#auth_unavailable)) olur.
* **Hesap bakiyesi**: Sıfır veya negatif ön ödemeli bakiyesi olan bir hesap HTTP 402 ([`balance_exhausted`](https://docs.blockvectra.com/tr/errors/#balance_exhausted)) döndürür; faturalandırma durumu onaylanamıyorsa yanıt HTTP 503 ([`billing_unavailable`](https://docs.blockvectra.com/tr/errors/#billing_unavailable)) olur.
* **Bağlantı sınırları**: Anahtar başına sınırın (20 bağlantı) veya hesap başına sınırın (50 bağlantı) aşılması HTTP 429 ([`ws_connection_limit`](https://docs.blockvectra.com/tr/errors/#ws_connection_limit)) döndürür.
* **Zincir kullanılabilirliği**: Bilinmeyen veya hizmet verilmeyen bir zincirin istenmesi HTTP 404 ([`unknown_chain`](https://docs.blockvectra.com/tr/errors/#unknown_chain)) döndürür.
* **Sunucu kapasitesi**: Sunucu meşgul veya aşırı yüklendiğinde, el sıkışma bir `Retry-After` başlığı ile birlikte HTTP 503 ([`overloaded`](https://docs.blockvectra.com/tr/errors/#overloaded)) döndürür.

Bağlantı kurulduktan sonra istemciler, standart JSON-RPC 2.0 isteklerini (`eth_blockNumber` veya `eth_call` gibi) ve UTF-8 metin çerçeveleri olarak biçimlendirilmiş abonelik kontrol yöntemlerini gönderebilir.

## Faturalandırma kuralları

* Bağlantı kurmak, boşta bir bağlantıyı açık tutmak ve ping/pong bağlantı sinyalleri faturalandırılmaz.
* `false` döndüren bir abonelik iptali de dahil olmak üzere başarılı `eth_subscribe` ve `eth_unsubscribe` çağrıları faturalandırılır; başarısız çağrılar faturalandırılmaz. Sıradan JSON-RPC çağrıları [JSON-RPC faturalandırma kurallarını](https://docs.blockvectra.com/tr/guides/billing-rules/) takip eder.
* `newHeads` bildirimleri, bağlantının kaç tane `newHeads` aboneliğine sahip olduğuna bakılmaksızın, bağlantı başına blok karması başına bir kez sayılır.
* `logs` bildirimleri, eşleşen loglara sahip blok karması ve aşaması başına abonelik başına bir kez sayılır; eşleşme olmayan bloklar faturalandırılmaz. Aynı blokta ve aşamada birden fazla eşleşen log olması ücreti katlamaz. Ayrı abonelikler, filtreleri örtüşse bile ayrı sayılır. Yeniden düzenleme logları (`removed: true`) ayrı bir birim oluşturur; aynı yükseklikteki yeni bir blok farklı bir karmaya sahiptir ve farklı bir birimdir.
* Bildirimler yalnızca soket gönderme arabelleğine başarıyla aktarıldıktan sonra faturalandırılır; kuyruğa alınan ancak aktarılmayan veya bırakılan bildirimler faturalandırılmaz. Bir `eth_unsubscribe` yanıtından önce kuyruğa alınan bildirimler aktarılmışsa sayılır. WebSocket mesajları hiçbir HTTP faturalandırma başlığı taşımaz; ölçülen CU için hesap kullanımına danışın.

## Abonelik yöntemleri

API standart Ethereum pub/sub arayüzünü uygular: `eth_subscribe` ve `eth_unsubscribe`.

### `newHeads`

Zincir tepesine yeni bir blok eklendiğinde yeni bir blok başlığı nesnesi yayınlar.

* **Abone olma isteği**:
  ```json
  {"jsonrpc":"2.0","id":1,"method":"eth_subscribe","params":["newHeads"]}
  ```
* **Abone olma yanıtı**: Opak bir onaltılık abonelik tanımlayıcısı döndürür:
  ```json
  {"jsonrpc":"2.0","id":1,"result":"0x1"}
  ```
* **Push bildirim çerçevesi**:
  ```json
  {"jsonrpc":"2.0","method":"eth_subscription","params":{"subscription":"0x1","result":{"number":"0x1b4","hash":"0x..."}}}
  ```

### `logs`

Belirtilen filtre ölçütleriyle eşleşen log olaylarını yayınlar.

* **Filtre gereksinimi**: Her `logs` abonelik filtresi bir `address` (bir sözleşme adresi veya adres dizisi) veya bir `topic0` (ilk topic konumu, null olmayan) **belirtmelidir**. Hiçbirini belirtmeyen bir filtre (`{}` veya `{"topics":[null,"0x..."]}` gibi), `-32602` ([`logs_filter_required`](https://docs.blockvectra.com/tr/errors/#logs_filter_required)) hata koduyla reddedilir.

* **Filtre sınırları**: En fazla 100 adres; konum başına en fazla 16 aday karma ile en fazla 4 topic konumu.

* **Filtre kapasitesi**: Aktif log filtreleri kapasiteye ulaşırsa, abonelik `-32022` ([`ws_filter_capacity`](https://docs.blockvectra.com/tr/errors/#ws_filter_capacity)) hata kodunu döndürür.

* **Zincir yeniden düzenlemeleri (reorg)**: Bir blok zincir reorg'u nedeniyle kaldırılırsa, kaldırılan loglar için log bildirimleri `"removed": true` taşır.

* **Abone olma isteği**:
  ```json
  {"jsonrpc":"2.0","id":2,"method":"eth_subscribe","params":["logs",{"address":"0x1234567890123456789012345678901234567890"}]}
  ```

### `eth_unsubscribe`

Abonelik tanımlayıcısını kullanarak etkin bir aboneliği sonlandırır.

* **Abonelikten çıkma isteği**:
  ```json
  {"jsonrpc":"2.0","id":3,"method":"eth_unsubscribe","params":["0x1"]}
  ```
* **Abonelikten çıkma yanıtı**:
  ```json
  {"jsonrpc":"2.0","id":3,"result":true}
  ```

## Çalıştırılabilir örnekler

**viem v2 (TypeScript)**

`createPublicClient` ve `webSocket` aktarımı aracılığıyla [viem](https://viem.sh) v2 kullanarak bağlanın. `{chain}` değerini hedef zincir tanımlayıcısıyla ve `{api_key}` değerini API key'inizle değiştirin:

```ts
import { createPublicClient, webSocket } from 'viem';

const apiKey = process.env.BLOCKVECTRA_API_KEY || '{api_key}';
const url = `wss://api.blockvectra.com/v1/robinhood_mainnet/${apiKey}`;

const client = createPublicClient({
  transport: webSocket(url),
});

// 1. Yeni blok başlıklarına abone olun (newHeads)
const unwatchBlocks = client.watchBlocks({
  onBlock: (block) => {
    console.log('Yeni blok başlığı alındı:', block.number, block.hash);
  },
  onError: (error) => {
    console.error('watchBlocks hatası:', error);
  },
});

// 2. Sözleşme olay loglarına abone olun (filtre address veya topic0 gerektirir)
const unwatchEvents = client.watchEvent({
  address: '0x1234567890123456789012345678901234567890',
  onLogs: (logs) => {
    console.log('Eşleşen loglar alındı:', logs);
  },
  onError: (error) => {
    console.error('watchEvent hatası:', error);
  },
});
```


  **Komut satırı (websocat / wscat)**

`websocat` veya `wscat` gibi komut satırı araçlarını kullanarak bağlanın ve ham JSON-RPC çerçeveleri gönderin:

```bash
# websocat kullanarak yol tabanlı API key ile bağlanın
websocat "wss://api.blockvectra.com/v1/{chain}/{api_key}"

# Alternatif olarak anahtarı istek başlığıyla iletin
websocat -H="x-api-key: {api_key}" "wss://api.blockvectra.com/v1/{chain}"

# Veya wscat kullanarak bağlanın
wscat -c "wss://api.blockvectra.com/v1/{chain}/{api_key}"
```

Etkileşimli oturuma abonelik komutları gönderin:

```json
{"jsonrpc":"2.0","id":1,"method":"eth_subscribe","params":["newHeads"]}
{"jsonrpc":"2.0","id":2,"method":"eth_subscribe","params":["logs",{"address":"0x1234567890123456789012345678901234567890"}]}
{"jsonrpc":"2.0","id":3,"method":"eth_unsubscribe","params":["0x1"]}
```


## Kapanış kodları ve istemci eylemleri

Sunucu bir WebSocket oturumunu sonlandırdığında, belirli bir kapanış kodu ve kısa bir neden içeren bir Kapanış (Close) çerçevesi gönderir. Aşağıdaki tablo, sunucu tarafından iletilen kapanış kodlarını ve önerilen eylemleri listeler:

|             Kapanış kodu | Neden dizesi                     | Açıklama                                                                                                                                                      | Yeniden denenebilir | İstemci eylemi                                                                                                                                                                                                                                                                  |
| -----------------------: | -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | :-----------------: | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [1001](https://docs.blockvectra.com/tr/errors/#1001) | `idle`                           | 3600 saniye (1 saat) boyunca abonelik veya mesaj içermeyen etkin olmayan bağlantı                                                                             |         Evet        | Gerektiğinde yeniden bağlanın.                                                                                                                                                                                                                                                  |
| [1003](https://docs.blockvectra.com/tr/errors/#1003) | `binary frames are not accepted` | İkili (binary) WebSocket çerçevesi alındı; yalnızca UTF-8 metin çerçeveleri kabul edilir                                                                      |        Hayır        | Otomatik olarak yeniden bağlanmayın. İstemciyi metin çerçeveleri gönderecek şekilde güncelleyin.                                                                                                                                                                                |
| [1009](https://docs.blockvectra.com/tr/errors/#1009) | `message too large`              | Gelen yük (payload) 1 MiB sınırını aştı                                                                                                                       |        Hayır        | Otomatik olarak yeniden bağlanmayın. Büyük istekleri bölün veya yük boyutunu azaltın.                                                                                                                                                                                           |
| [1012](https://docs.blockvectra.com/tr/errors/#1012) | `service restart`                | Sunucu yeniden başlatılıyor veya oturum maksimum yaşam süresine (24 saat) ulaştı                                                                              |         Evet        | Rastgele gecikmeli (jitter) geri çekilme kullanarak yeniden bağlanın, abonelikleri yeniden oluşturun ve kaçırılan verileri geriye dönük doldurun.                                                                                                                               |
| [1013](https://docs.blockvectra.com/tr/errors/#1013) | `chain unavailable`              | Zincir kullanılamıyor                                                                                                                                         |         Evet        | Tam gecikmeli (full-jitter) üstel geri çekilme kullanarak yeniden bağlanın, abonelikleri yeniden oluşturun ve kaçırılan verileri geriye dönük doldurun.                                                                                                                         |
| [1013](https://docs.blockvectra.com/tr/errors/#1013) | `overloaded`                     | Sunucu geçici olarak aşırı yüklendi                                                                                                                           |         Evet        | Tam gecikmeli (full-jitter) üstel geri çekilme kullanarak yeniden bağlanın, abonelikleri yeniden oluşturun ve kaçırılan verileri geriye dönük doldurun.                                                                                                                         |
| [4402](https://docs.blockvectra.com/tr/errors/#4402) | `insufficient balance`           | Hesap bakiyesi tükendi                                                                                                                                        |        Hayır        | Otomatik olarak yeniden bağlanmayın. [Bakiyenizi yükleyin, ardından yeniden bağlanın](https://docs.blockvectra.com/tr/guides/billing-rules/).                                                                                                                                                               |
| [4404](https://docs.blockvectra.com/tr/errors/#4404) | `invalid api key`                | API key bilinmiyor, devre dışı bırakılmış veya iptal edilmiş                                                                                                  |        Hayır        | Otomatik olarak yeniden bağlanmayın. Yeniden bağlanmadan önce konsolda API key'i doğrulayın veya yenileyin.                                                                                                                                                                     |
| [4408](https://docs.blockvectra.com/tr/errors/#4408) | `slow consumer`                  | Sunucu, push kuyruğu 512 KiB'yi geçen oturumu kapatır ve bekleyen bildirimleri bırakır; istemciler bir kapanış çerçevesi almayabilir (tarayıcı 1006 bildirir) |         Evet        | Beklenmeyen bağlantı kesilmelerini (kapanış çerçevesi alınmadı, tarayıcı 1006 bildiriyor) 4408 gibi ele alın: geri çekilme ile yeniden bağlanın, abonelikleri yeniden oluşturun ve bırakılan verileri `eth_getLogs` ile doldurun; daha azına abone olun veya daha hızlı okuyun. |
| [4429](https://docs.blockvectra.com/tr/errors/#4429) | `push rate exceeded`             | Bildirim hızı 1,000 push/saniye sınırını aştı                                                                                                                 |         Evet        | Abonelikleri azaltın veya filtreleri daraltın; geri çekilme ile yeniden bağlanın, yeniden abone olun ve geriye dönük doldurun.                                                                                                                                                  |
| [4503](https://docs.blockvectra.com/tr/errors/#4503) | `billing unavailable`            | Faturalandırma geçici olarak kullanılamıyor                                                                                                                   |         Evet        | Geçici durum; tam gecikmeli (full-jitter) üstel geri çekilme kullanarak yeniden bağlanın.                                                                                                                                                                                       |

## Yeniden bağlanma ve üstel geri çekilme

Bağlantılar koptuğunda senkronize yeniden bağlanma fırtınalarını önlemek için istemciler tam gecikmeli (full-jitter) üstel geri çekilme uygulamalıdır:

* **Geri çekilme formülü**: n'inci yeniden bağlanma girişiminden önce (n = 0, 1, 2, ...), rastgele ve tekdüze (uniformly at random) seçilen bir süre boyunca bekleyin:
  ```
  delay = random(0, min(20s, 0.5s * 2^n))
  ```
* **Sayacı sıfırlama**: Yeniden deneme sayacı n'i yalnızca en az `60 saniye` boyunca kesintisiz, kararlı bir bağlantıyı sürdürdükten sonra 0'a sıfırlayın.
* **Kapanış kodu 1012**: Senkronize yeniden bağlanma artışlarını önlemek için ilk yeniden bağlanma girişiminden önce rastgele bir başlangıç gecikmesi uygulayın.
* **Yeniden denenemeyen kodlar**: [4402](https://docs.blockvectra.com/tr/errors/#4402), [4404](https://docs.blockvectra.com/tr/errors/#4404), [1003](https://docs.blockvectra.com/tr/errors/#1003) veya [1009](https://docs.blockvectra.com/tr/errors/#1009) durumlarında otomatik olarak yeniden bağlanmayın.

### Yeniden bağlandıktan sonra kaçırılan verileri geriye dönük doldurma

WebSocket abonelikleri bağlantılar boyunca kalıcı değildir; bir bağlantı kesintisi sırasında yayınlanan bildirimler sunucuda tutulmaz. Yeniden bağlanmanın ardından istemciler bir yakalama (catch-up) stratejisi yürütmelidir:

1. **`eth_getLogs` ile logları geriye dönük doldurma**:
   * Başarıyla işlenen en yüksek blok numarasını (`last_processed_block`) kalıcı olarak saklayın.
   * Canlı olayları yakalamak için yeniden bağlanma anında hemen `eth_subscribe("logs", ...)` çağrısı yapın.
   * `fromBlock: last_processed_block + 1` ve `toBlock: "latest"` (veya canlı akıştan alınan ilk blok) ile `eth_getLogs` aracılığıyla kaçırılan blokları sorgulayın.
   * Bağlantı kesintisi boşluğu ağın `max_logs_block_range` değerini (`GET /v1/chains` üzerinden) aşıyorsa, sorguları bu sınırı aşmayan parçalara bölün.
   * Benzersiz demet `(blockHash, transactionHash, logIndex)` kullanarak sorgu sınırı boyunca log girdilerini tekilleştirin.
2. **`eth_getBlockByNumber` ile blok başlıklarını geriye dönük doldurma**:
   * Bağlantı kesilmeden önce alınan en son blok numarasını ve karmasını kaydedin.
   * `newHeads` aboneliğini yeniden başlatın.
   * `eth_getBlockByNumber("latest", false)` sorgulayın ve eksik ara blokları sıralı olarak getirin. Reorg'ları tespit etmek için `parentHash` zincir sürekliliğini doğrulayın.

## Sınırlar

| Sınır                                               | Değer                                                                   | Aşıldığında sonuç                                                   |
| --------------------------------------------------- | ----------------------------------------------------------------------- | ------------------------------------------------------------------- |
| WebSocket bağlantısı başına abonelikler             | 100                                                                     | `-32022` [`subscription_limit`](https://docs.blockvectra.com/tr/errors/#subscription_limit)     |
| WebSocket bağlantısı başına `newHeads` abonelikleri | 4                                                                       | `-32022` [`subscription_limit`](https://docs.blockvectra.com/tr/errors/#subscription_limit)     |
| `logs` abonelik filtresi gereksinimleri             | Bir `address` veya `topic0` (`topics` içindeki ilk konum) belirtmelidir | `-32602` [`logs_filter_required`](https://docs.blockvectra.com/tr/errors/#logs_filter_required) |

## Sonraki adımlar

* BlockVectra'nın indekslediği tüm veri kümelerini görmek için [veri kümeleri dizinine göz atın](https://blockvectra.com/tr/data/).
* Hesabınızın neleri içerdiğini kontrol etmek için [ücretsiz planı ve fiyatlandırmayı inceleyin](https://blockvectra.com/tr/pricing/#free).
* Bir API key oluşturmak için [konsolda oturum açın](https://console.blockvectra.com/login/?next=%2Fkeys%2F).
