Ana içeriğe geç

Redis adaptörü

Nasıl çalışır

Redis adaptörü, Redis Pub/Sub mekanizmasını kullanır.

Birden fazla istemciye (örneğin, io.to("room1").emit() veya socket.broadcast.emit()) gönderilen her paket:

  • mevcut sunucuya bağlı tüm eşleşen istemcilere gönderilir
  • bir Redis kanalında yayınlanır ve kümenin diğer Socket.IO sunucuları tarafından alınır

Bu adaptörün kaynak koduna buradan ulaşabilirsiniz.

Desteklenen özellikler

Özelliksocket.io sürümüDestek
Socket yönetimi4.0.0✅ EVET (sürüm 6.1.0'dan beri)
Sunucular arası iletişim4.1.0✅ EVET (sürüm 7.0.0'dan beri)
Onaylı yayın4.5.0✅ EVET (sürüm 7.2.0'dan beri)
Bağlantı durumu kurtarma4.6.0❌ HAYIR

Kurulum

npm install @socket.io/redis-adapter

Uyumluluk tablosu

Redis Adaptör sürümüSocket.IO sunucu sürümü
4.x1.x
5.x2.x
6.0.x3.x
6.1.x4.x
7.x ve üzeri4.3.1 ve üzeri

Kullanım

ipucu

Yeni geliştirmeler için, Redis 7.0'de tanıtılan parçalı Pub/Sub özelliğinden yararlanan parçalı adaptörü kullanmanızı öneririz.

redis paketi ile

uyarı

redis paketinin yeniden bağlantıdan sonra Redis aboneliklerini geri yükleme konusunda sorunları olduğu görülmektedir:

Bunun yerine ioredis paketini kullanmak isteyebilirsiniz.

import { createClient } from "redis";
import { Server } from "socket.io";
import { createAdapter } from "@socket.io/redis-adapter";

const pubClient = createClient({ url: "redis://localhost:6379" });
const subClient = pubClient.duplicate();

await Promise.all([
pubClient.connect(),
subClient.connect()
]);

const io = new Server({
adapter: createAdapter(pubClient, subClient)
});

io.listen(3000);

redis paketi ve bir Redis kümesi ile

import { createCluster } from "redis";
import { Server } from "socket.io";
import { createAdapter } from "@socket.io/redis-adapter";

const pubClient = createCluster({
rootNodes: [
{
url: "redis://localhost:7000",
},
{
url: "redis://localhost:7001",
},
{
url: "redis://localhost:7002",
},
],
});
const subClient = pubClient.duplicate();

await Promise.all([
pubClient.connect(),
subClient.connect()
]);

const io = new Server({
adapter: createAdapter(pubClient, subClient)
});

io.listen(3000);

ioredis paketi ile

import { Redis } from "ioredis";
import { Server } from "socket.io";
import { createAdapter } from "@socket.io/redis-adapter";

const pubClient = new Redis();
const subClient = pubClient.duplicate();

const io = new Server({
adapter: createAdapter(pubClient, subClient)
});

io.listen(3000);

ioredis paketi ve bir Redis kümesi ile

import { Cluster } from "ioredis";
import { Server } from "socket.io";
import { createAdapter } from "@socket.io/redis-adapter";

const pubClient = new Cluster([
{
host: "localhost",
port: 7000,
},
{
host: "localhost",
port: 7001,
},
{
host: "localhost",
port: 7002,
},
]);
const subClient = pubClient.duplicate();

const io = new Server({
adapter: createAdapter(pubClient, subClient)
});

io.listen(3000);

Redis parçalı Pub/Sub ile

Parçalı Pub/Sub, Redis 7.0'da, küme modunda Pub/Sub kullanımını ölçeklendirmek amacıyla tanıtılmıştır.

Referans: https://redis.io/docs/interact/pubsub/#sharded-pubsub

createShardedAdapter() metodu ile özel bir adaptör oluşturulabilir:

import { Server } from "socket.io";
import { createClient } from "redis";
import { createShardedAdapter } from "@socket.io/redis-adapter";

const pubClient = createClient({ host: "localhost", port: 6379 });
const subClient = pubClient.duplicate();

await Promise.all([
pubClient.connect(),
subClient.connect()
]);

const io = new Server({
adapter: createShardedAdapter(pubClient, subClient)
});

io.listen(3000);

Minimum gereksinimler:

uyarı

Şu anda ioredis paketi ve bir Redis kümesi ile parçalı adaptör kullanmak mümkün değildir (referans).

Seçenekler

Varsayılan adaptör

AdAçıklamaVarsayılan değer
keyRedis Pub/Sub kanalları için ön ek.socket.io
requestsTimeoutBu zaman aşımından sonra adaptör, yanıtlar için beklemeyi durduracaktır.5_000
publishOnSpecificResponseChannelİsteği yapan düğüme özel kanala yanıtı yayımlayıp yayımlamayacağını belirler.false
parserRedis'e gönderilen ve Redis'den alınan mesajların kodlanması ve çözülmesi için kullanılacak ayrıştırıcı.-
ipucu

publishOnSpecificResponseChannel seçeneğini true olarak ayarlamak daha verimlidir çünkü yanıtlar (örneğin, fetchSockets() veya serverSideEmit() çağrısı yapıldığında) yalnızca isteği yapan sunucuya gönderilir, tüm sunuculara değil.

Ancak, şu anda geriye dönük uyumluluk için varsayılan olarak false'dur.

Parçalı adaptör

AdAçıklamaVarsayılan değer
channelPrefixRedis Pub/Sub kanalları için ön ek.socket.io
subscriptionModeAbonelik modu, adaptör tarafından kullanılan Redis Pub/Sub kanalı sayısını etkiler.dynamic

subscriptionMode seçeneği için kullanılabilir değerler:

DeğerPub/Sub kanalları sayısıAçıklama
staticher ad alanı için 2Dinamik ad alanları ile kullanıldığında faydalıdır.
dynamic (varsayılan)her ad alanı için (2 + 1 her kamu odası başına)Bazı odalarda düşük sayıda istemci olduğunda faydalıdır (bu durumda yalnızca birkaç Socket.IO sunucusu bilgilendirilir).
dynamic-privateher ad alanı için (2 + 1 her oda başına)dynamic gibi ama özel odalar için ayrı kanallar oluşturur. socket.emit() çağrıları aracılığıyla çok sayıda 1:1 iletişim olduğunda faydalıdır.

Yaygın sorular

Redis'te herhangi bir veri depolanıyor mu?

Hayır, Redis adaptörü, Socket.IO sunucuları arasında paketleri iletmek için Pub/Sub mekanizmasını kullanır; bu nedenle Redis'te anahtarlar depolanmaz.

Redis adaptörünü kullanırken hala yapışkan oturumları etkinleştirmem gerekir mi?

Evet. Bunu yapmamak, HTTP 400 yanıtlarına neden olacaktır (socket.io oturumundan haberdar olmayan bir sunucuya ulaşıyorsunuz).

Daha fazla bilgi burada bulunabilir.

Redis sunucusu kapandığında ne olur?

Redis sunucusuna olan bağlantı kesildiğinde, paketler yalnızca mevcut sunucuya bağlı istemcilere gönderilir.

socket.io-redis'den geçiş

Paket, socket.io-redis'den @socket.io/redis-adapter olarak v7 sürümünde yeniden adlandırılmıştır. Bu, Redis yayıncılarının adını (@socket.io/redis-emitter) yansıtmak amacıyla yapılmıştır.

Yeni pakete geçiş yapmak için, kendi Redis istemcilerinizi sağladığınızdan emin olmalısınız, çünkü paket artık kullanıcı adına Redis istemcileri oluşturmayacaktır.

Önce:

const redisAdapter = require("socket.io-redis");

io.adapter(redisAdapter({ host: "localhost", port: 6379 }));

Sonra:

const { createClient } = require("redis");
const { createAdapter } = require("@socket.io/redis-adapter");

const pubClient = createClient({ url: "redis://localhost:6379" });
const subClient = pubClient.duplicate();

io.adapter(createAdapter(pubClient, subClient));
ipucu

Socket.IO sunucuları arasındaki iletişim protokolü güncellenmediğinden, bazı sunucular socket.io-redis ve diğerleri @socket.io/redis-adapter ile aynı anda bulunabilir.

En son sürümler

SürümYayın tarihiYayın notlarıFark
8.3.0Mart 2024link8.2.1...8.3.0
8.2.1Mayıs 2023link8.2.0...8.2.1
8.2.0Mayıs 2023link8.1.0...8.2.0
8.1.0Şubat 2023link8.0.0...8.1.0
8.0.0Aralık 2022link7.2.0...8.0.0
7.2.0Mayıs 2022link7.1.0...7.2.0

Tam güncelleme günlüğü

Yayıncı

Redis yayıncısı, başka bir Node.js sürecinden bağlı istemcilere paketler göndermeyi sağlar:

Bu yayıncı, birkaç dilde de mevcuttur:

Kurulum

npm install @socket.io/redis-emitter redis

Kullanım

import { Emitter } from "@socket.io/redis-emitter";
import { createClient } from "redis";

const redisClient = createClient({ url: "redis://localhost:6379" });

redisClient.connect().then(() => {
const emitter = new Emitter(redisClient);

setInterval(() => {
emitter.emit("time", new Date);
}, 5000);
});

Not: redis@3 ile, Redis istemcisi üzerinde connect() çağrısı yapmanıza gerek yoktur:

import { Emitter } from "@socket.io/redis-emitter";
import { createClient } from "redis";

const redisClient = createClient({ url: "redis://localhost:6379" });
const emitter = new Emitter(redisClient);

setInterval(() => {
emitter.emit("time", new Date);
}, 5000);

Lütfen yardım kılavuzuna buradan ulaşın.

socket.io-emitter'dan geçiş

Paket, socket.io-emitter'dan @socket.io/redis-emitter olarak v4 sürümünde yeniden adlandırılmıştır. Bu, Redis ile ilişkiyi daha iyi yansıtmak amacıyla yapılmıştır.

Yeni pakete geçiş yapmak için, kendi Redis istemcilerinizi sağladığınızdan emin olmalısınız, çünkü paket artık kullanıcı adına Redis istemcileri oluşturmayacaktır.

Önce:

const io = require("socket.io-emitter")({ host: "127.0.0.1", port: 6379 });

Sonra:

const { Emitter } = require("@socket.io/redis-emitter");
const { createClient } = require("redis");

const redisClient = createClient();
const io = new Emitter(redisClient);

En son sürümler

SürümYayın tarihiYayın notlarıFark
5.1.0Ocak 2023link5.0.0...5.1.0
5.0.0Eylül 2022link4.1.1...5.0.0
4.1.1Ocak 2022link4.1.0...4.1.1
4.1.0Mayıs 2021link4.0.0...4.1.0
4.0.0Mart 2021link3.2.0...4.0.0

Tam güncelleme günlüğü