Odalar
Bir oda, soketlerin katılabileceği
ve çıkabileceği
keyfi bir kanaldır. Belirli bir istemci alt kümesine olayları yayınlamak için kullanılabilir:
Lütfen odaların sunucuya özgü bir kavram olduğunu unutmayın (yani, istemci katıldığı odaların listesini göremez).
Katılma ve ayrılma
Bir soketi belirli bir kanala abone etmek için katıl
fonksiyonunu çağırabilirsiniz:
io.on("connection", (socket) => {
socket.join("some room");
});
Ve ardından yayın yaparken veya gönderirken to
veya in
(ikisi de aynı) kullanın:
io.to("some room").emit("some event");
Ya da bir odayı hariç tutabilirsiniz:
io.except("some room").emit("some event");
Aynı anda birden fazla odaya da yayın yapabilirsiniz:
io.to("room1").to("room2").to("room3").emit("some event");
Bu durumda, bir birleşim gerçekleştirilir: en az bir odada bulunan her soket olayı bir kez alır (soket iki veya daha fazla odadaysa bile).
Belirli bir soketten bir odaya yayın yapmak da mümkündür:
io.on("connection", (socket) => {
socket.to("some room").emit("some event");
});
Bu durumda, gönderici hariç odada bulunan her soket olayı alacaktır.
Bir kanaldan çıkmak için katıl
ile aynı şekilde çık
fonksiyonunu çağırırsınız.
Örnek kullanım senaryoları
- belirli bir kullanıcıya ait her cihaz/tab için veri yayınlamak
function computeUserIdFromHeaders(headers) {
// implementasyon yapılacak
}
io.on("connection", async (socket) => {
const userId = await computeUserIdFromHeaders(socket.handshake.headers);
socket.join(userId);
// ve daha sonra
io.to(userId).emit("hi");
});
- belirli bir varlık hakkında bildirim göndermek
io.on("connection", async (socket) => {
const projects = await fetchProjects(socket);
projects.forEach(project => socket.join("project:" + project.id));
// ve daha sonra
io.to("project:4321").emit("project updated");
});
Bağlantının Kesilmesi
Bağlantı kesildiğinde, soketler otomatik olarak bulundukları tüm kanallardan çık
yaparlar ve sizin tarafınızdan özel bir temizleme işlemi yapılması gerekmez.
Bir soketin bulunduğu odaları disconnecting
olayını dinleyerek alabilirsiniz:
io.on("connection", socket => {
socket.on("disconnecting", () => {
console.log(socket.rooms); // Set en az soket ID'sini içerir
});
socket.on("disconnect", () => {
// socket.rooms.size === 0
});
});
Birden Fazla Socket.IO Sunucusuyla
global broadcasting
gibi, odalara yayın yapmak da birden fazla Socket.IO sunucusuyla çalışır.
Sadece varsayılan Adaptörü
Redis Adaptörü ile değiştirmelisiniz. Hakkında daha fazla bilgi burada
.
Uygulama Detayları
"Oda" özelliği, bir Adaptör olarak adlandırdığımız bir yapı ile uygulanır. Bu Adaptör, şu işlevlerden sorumlu bir sunucu tarafı bileşenidir:
- Soket örnekleri ile odalar arasındaki ilişkileri saklamak
- Olayları tüm (veya bir alt küme) istemcilere yayınlamak
Varsayılan bellek içi adaptörün kodunu burada bulabilirsiniz.
Temelde, iki ES6 Maps içerir:
sids
:Map>
rooms
:Map>
socket.join("the-room")
çağrısı aşağıdaki sonuçları doğurur:
sids
Haritasında, soket ID'siyle tanımlanan Set'e "the-room" eklenirrooms
Haritasında, "the-room" dizgesiyle tanımlanan Set'e soket ID'si eklenir
Bu iki harita daha sonra yayınlama sırasında kullanılır:
- Tüm soketlere yayın (
io.emit()
)sids
Haritasında döngü yapar ve paketi tüm soketlere gönderir - Belirli bir odaya yayın (
io.to("room21").emit()
)rooms
Haritasındaki Set'te döngü yaparak eşleşen tüm soketlere paketi gönderir
Bu nesnelere erişebilirsiniz:
// ana isim alanı
const rooms = io.of("/").adapter.rooms;
const sids = io.of("/").adapter.sids;
// özel isim alanı
const rooms = io.of("/my-namespace").adapter.rooms;
const sids = io.of("/my-namespace").adapter.sids;
Notlar:
- Bu nesneler doğrudan değiştirilmemelidir; her zaman
socket.join(...)
vesocket.leave(...)
kullanmalısınız. çoklu sunucu
kurulumu sırasında,rooms
vesids
nesneleri Socket.IO sunucuları arasında paylaşılmaz (bir oda yalnızca bir sunucuda "var" olabilir ve diğerinde olmayabilir).
Oda Olayları
socket.io@3.1.0
sürümünden itibaren, temel Adaptör aşağıdaki olayları yayar:
create-room
(argüman: oda)delete-room
(argüman: oda)join-room
(argüman: oda, id)leave-room
(argüman: oda, id)
Örnek:
io.of("/").adapter.on("create-room", (room) => {
console.log(`room ${room} was created`);
});
io.of("/").adapter.on("join-room", (room, id) => {
console.log(`socket ${id} has joined room ${room}`);
});