Uzak olaylar ve geri çağrılar

*Bu içerik, yapay zekâ (beta) kullanılarak çevrildi ve hatalar içerebilir. Sayfayı İngilizce görüntülemek için buraya tıkla.

Roblox deneyimleri varsayılan olarak çok oyunculudur, bu nedenle tüm deneyimler doğası gereği sunucu ve oyuncuların bağlı istemcileri arasında iletişim kurar.En basit durumda, oyuncular karakterlerini hareket ettirirken, devletler gibi belirli Humanoid özellikleri sunucuya iletilir ve bu bilgi diğer bağlı müşterilere iletilir.

Uzak olaylar ve geri çağrılar, istemci-sunucu sınırı boyunca iletişim kurmanıza izin verir çapraz :

  • RemoteEvents tek yönlü iletişimi etkinleştir (bir istek göndermek ve bir cevap için teslim etmemek ).
  • UnreliableRemoteEvents sürekli değişen veya oyun durumuna kritik olmayan veriler için tek yönlü iletişimi etkinleştirinBu olaylar, geliştirilmiş ağ sözleşme imzalamaiçin sipariş verme ve güvenilirliği takas eder.
  • RemoteFunctions iki yönlü iletişimi etkinleştir (bir istek gönderip alıcıdan bir yanıt alıncaya kadar bekle).

bağlanabilir etkinliklerden farklı olarak, daha sınırlı bir kullanım alanına sahip uzaktan etkinlikler ve işlevler için kullanım durumları listelenmek için çok fazladır:

  • Oyunculuk - Bir oyuncunun bir seviyenin sonuna ulaşması gibi temel oynanış, uzaktan bir olay gerektirebilir.Bir istemci kodu sunucuyu bilgilendirir ve sunucu kodları oyuncunun konumunu sıfırlar.
  • Sunucu doğrulaması - Eğer bir oyuncu bir iksir içmeye çalışırsa, aslında o iksiri var mı var? Adaletin sağlanması için, sunucunun bir deneyim için gerçek kaynağı olması gerekir.Bir istemci kodu, oyuncunun bir iksir içtiğini bildirmek için uzaktaki bir olayı kullanabilir ve ardından sunucu kodları oyuncunun gerçekten bu iksiri alıp almadığını ve herhangi bir faydanın verilip verilmeyeceğini karar verebilir.
  • Kullanıcı arayüzü güncellemeleri - Oyun durumu değiştiğinde, sunucu kodları uzaktaki olayları kullanarak kullanıcılara puan, hedefler, vb. değişiklikleri bildirebilir
  • Deneyim içi Pazar satışları - Uzaktan işlevleri kullanan bir örnek uygulama için, bakınız Hızlı abonelik satın alımları.

Hızlı referans

Aşağıdaki tablolar, istemci ve sunucu arasında iletişim kurmak için nasıl RemoteEvents ve RemoteFunctions kullanılacağına ilişkin hızlı bir referans olarak hizmet eder.

>
İstemci → Sunucu
MüşteriRemoteEvent:FireServer(args)
SunucuRemoteEvent.OnServerEvent:Connect(function(player, args))
Sunucu → Klient >
SunucuRemoteEvent:FireClient(player, args)
MüşteriRemoteEvent.OnClientEvent:Connect(function(args))
Sunucu → Tüm Klientler >
SunucuRemoteEvent:FireAllClients(args)
MüşteriRemoteEvent.OnClientEvent:Connect(function(args))

Uzak olaylar

Bir RemoteEvent nesnesi, bir yanıt vermeden istemci-sunucu sınırı arasında asenkron, tek yönlü iletişimi kolaylaştırır.

Studio'daki Gezgini penceresi aracılığıyla yeni bir oluşturmak için:

  1. RemoteEvent 'yi yerleştirmek istediğiniz konteynere tıklayın.Hem sunucunun hem de istemcinin erişimini sağlamak için, her iki tarafın da görebileceği bir yerde olmalıdır, örneğin ReplicatedStorage, ancak bazı durumlarda bunu Workspace veya bir Tool içinde saklamak uygundur.
  2. Konteynerin adının sağında görünen düğmesine tıklayın ve bir Uzak Etkinlik durumgirin.
  3. Amaçlarını tanımlamak için örneğin adını yeniden adlandırın.

Bir RemoteEvent oluşturduktan sonra, bir yönlü iletişimi müşteriden sunucuya , sunucudan müşteriye veya sunucudan tüm müşterilere kolaylaştırabilir.

İstemci → Sunucu
>

Sunucu → Klient
>

Sunucu → Tüm Klientler
>

Müşteri → sunucu

Bir ı kullanarak sunucu üzerinde bir olay tetikleyebilirsiniz, çağırarak yöntemi bir üzerinde .Eğer FireServer() 'a argüman geçirirseniz, bazı sınırlamalarla sunucudaki olay işleyicisine geçerler.Sunucudaki etkinlik işlemcisinin ilk parametresinin daima çağıran istemcinin Player nesnesi olduğunu ve ek parametlerin takip etgeldiğini unutmayın.

MüşteriRemoteEvent:FireServer(args)
SunucuRemoteEvent.OnServerEvent:Connect(function(player, args))

Aşağıdaki Script bir etkinlik işleyicisini sunucuda yeni bir OnServerEvent oluşturan ile bağlar Part çeker.Eşlik eden daha sonra istenen ve parça için ve ile örneğin üzerinde çağrır.

Etkinlik Bağlantısı - Kod

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Workspace = game:GetService("Workspace")
-- Uzak etkinlik durumreferans alın
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function onCreatePart(player, partColor, partPosition)
print(player.Name .. " fired the RemoteEvent")
local newPart = Instance.new("Part")
newPart.Color = partColor
newPart.Position = partPosition
newPart.Parent = Workspace
end
-- İşlevi etkinliğe bağla
remoteEvent.OnServerEvent:Connect(onCreatePart)
Etkinlik ateşleme - Yerel Kod

local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Uzak etkinlik durumreferans alın
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- Uzaktaki olayı ateşle ve ek argümanlar geçir
remoteEvent:FireServer(Color3.fromRGB(255, 0, 0), Vector3.new(0, 25, -20))

Sunucu → istemci

Bir Script ı bir müşteri üzerinde bir olay tetiklemek için çağırarak FireClient() yöntemini bir RemoteEvent.FireClient() için ilk argüman, olaya yanıt vermek istediğiniz müşterinin Player nesnesidir ve ek argümanlar belirli sınırlamalarla müşteriye geçer.Etkinlik işlemcisinin ilk argümanı olarak Player nesneyi dahil etmesi gerekmediğini unutmayın, çünkü Players.LocalPlayer ile oyuncuyu istemciye belirleyebilirsiniz.

SunucuRemoteEvent:FireClient(player, args)
MüşteriRemoteEvent.OnClientEvent:Connect(function(args))

Aşağıdaki LocalScript bir etkinlik işleyicisini OnClientEvent etkinliğine bağlar.Eşlik eden Script daha sonra sunucuya gelen oyuncuları dinler ve her biri için rastgele verilerle FireClient() çağrır.

Etkinlik Bağlantısı - YerelScript

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
-- Uzak etkinlik durumreferans alın
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local player = Players.LocalPlayer
local function onNotifyPlayer(maxPlayers, respawnTime)
print("[Client] Event received by player", player.Name)
print(maxPlayers, respawnTime)
end
-- İşlevi etkinliğe bağla
remoteEvent.OnClientEvent:Connect(onNotifyPlayer)
Etkinlik Ateşleme - Kod

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
-- Uzak etkinlik durumreferans alın
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- Gelen oyuncuları dinleyin ve her birine uzaktan olay gönderin
local function onPlayerAdded(player)
print("[Server] Firing event to player", player.Name)
remoteEvent:FireClient(player, Players.MaxPlayers, Players.RespawnTime)
end
Players.PlayerAdded:Connect(onPlayerAdded)

Sunucu → tüm istemciler

Tüm istemcilerde bir etkinliği tetiklemek için Script yöntemini çağırarak FireAllClients() yöntemini bir RemoteEvent üzerinde kullanabilirsiniz.FireClient() yerine, FireAllClients() yöntemi tüm müşterilere ateşlediği için bir Player nesnesine ihtiyaç duymaz çünkü tüm müşterilere RemoteEvent ateş eder.

SunucuRemoteEvent:FireAllClients(args)
MüşteriRemoteEvent.OnClientEvent:Connect(function(args))

Aşağıdaki LocalScript bir etkinlik işleyicisini kalan bir geri sayım süresi üreten OnClientEvent olayına bağlar.Eşlik eden daha sonra her saniye bir döngüde 'i tüm müşteriler için ateşlemek için çağırır.

Etkinlik Bağlantısı - YerelScript

local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Uzak etkinlik durumreferans alın
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function onTimerUpdate(seconds)
print(seconds)
end
-- İşlevi etkinliğe bağla
remoteEvent.OnClientEvent:Connect(onTimerUpdate)
Etkinlik Ateşleme - Kod

local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Uzak etkinlik durumreferans alın
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local countdown = 5
-- Süre dolana kadar her saniye uzaktan etkinlik ateşleyin
for timeRemaining = -1, countdown do
remoteEvent:FireAllClients(countdown - timeRemaining)
task.wait(1)
end

Uzak geri çağrılar

Bir RemoteFunction nesnesi, istemci-sunucu sınırı boyunca senkron, iki yönlü iletişimi kolaylaştırır.Uzak işlevin göndericisi, alıcıdan bir yanıt alana kadar verecektir.

Studio'daki Gezgini penceresi aracılığıyla yeni bir oluşturmak için:

  1. RemoteFunction 'yi yerleştirmek istediğiniz konteynere tıklayın.Hem sunucunun hem de istemcinin erişimini sağlamak için, her iki tarafın da görebileceği bir yerde olmalıdır, örneğin ReplicatedStorage, ancak bazı durumlarda bunu Workspace veya bir Tool içinde saklamak uygundur.
  2. Konteynerin adının sağında görünen düğmesine tıklayın ve bir Uzak Fonksiyon durumgirin.
  3. Amaçlarını tanımlamak için örneğin adını yeniden adlandırın.

Bir RemoteFunction oluşturduktan sonra, müşteri ve sunucu veya sunucu ve müşteri arasındaki çift yönlü iletişimi kolaylaştırabilir.

İstemci → Sunucu → İstemci

Sunucu → Klient → Sunucu
>

İstemci → sunucu → istemci

Bir ı kullanarak sunucu üzerinde bir işlev çağırabilirsiniz, yöntemi bir üzerinde çağırarak.Bir uzaktan etkinlikten farklı olarak, çağrılan uzaktan etkinlik , geri dönene kadar LocalScript çıkarır RemoteFunction.InvokeServer() geçirdiğiniz argümanlar, belirli kısıtlamalarla OnServerInvoke``Class.RemoteFunctionçağrısına geçiyor.Aynı RemoteFunction 'ye çok sayıda geri çağrı tanımlarsanız, sadece son tanımın yürütüldüğünü unutmayın.

MüşteriRemoteFunction:InvokeServer(args)
SunucuRemoteFunction.OnServerInvoke = function(player, args)

Aşağıdaki Script çağrı işlevini tanımlar OnServerInvoke ve talep edilen Part değeri aracılığıyla istenen return geri döndürür.Eşlik eden LocalScript daha sonra talep edilen parça rengi ve konumunu tanımlayan ekstra argümanlarla çağrır InvokeServer() .

Geri Çağırma Bağlantısı - Kod

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Workspace = game:GetService("Workspace")
-- Uzak işlev örneğine referans alın
local remoteFunction = ReplicatedStorage:FindFirstChildOfClass("RemoteFunction")
-- Geri çağırma işlevi
local function createPart(player, partColor, partPosition)
print(player.Name .. " requested a new part")
local newPart = Instance.new("Part")
newPart.Color = partColor
newPart.Position = partPosition
newPart.Parent = Workspace
return newPart
end
-- İşlevi uzaktaki işlevin geri çağrısı olarak ayarla
remoteFunction.OnServerInvoke = createPart
Etkinlik Daveti - Yerel Kod

local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Uzak işlev örneğine referans alın
local remoteFunction = ReplicatedStorage:FindFirstChildOfClass("RemoteFunction")
-- Geri çağrı yaparken bir renk ve konum geçirin
local newPart = remoteFunction:InvokeServer(Color3.fromRGB(255, 0, 0), Vector3.new(0, 25, -20))
-- Döndürülen parça referansını çıkart
print("The server created the requested part:", newPart)

Sunucu → istemci → sunucu

Bir Script ı kullanarak istemciye bir işlev çağırabilirsiniz InvokeClient() yöntemi üzerinde bir RemoteFunction , ancak şu şekilde ciddi riskleri vardır:

  • Eğer istemci bir hata atarsa, sunucu da hata atar.
  • Müşteri çağrılırken bağlantı keserse, InvokeClient() bir hata atar.
  • Müşteri bir değer dönmediğinde, sunucu sonsuza dek verir.

Bir GUI'yi güncelleme gibi iki yönlü iletişim gerektirmeyen eylemler için, bir RemoteEvent kullanın ve sunucudan istemciye iletişim kurun.

Argüman sınırları

Bir RemoteEvent ateşlediğinizde veya bir RemoteFunction çağrısı yaptığınızda, olayla veya geri çağrı işleviyle geçirdiğiniz herhangi bir argümanı yönlendirir.Bir Enum , Instance veya diğer türde herhangi bir Roblox nesnesi, sayılar, dize ve booleans gibi Luau türleri de dahil olmak üzere, ayrıca aşağıdaki sınırlamaları dikkatlice araştırmalısınız.

Dize olmayan indeksler

Geçmiş bir tablonun herhangi bir indeksi bir Instance , kullanıcı verisi veya fonksiyonu gibi non-string türler ise, Roblox otomatik olarak bu indeksleri dizeye dönüştürür.

Etkinlik Bağlantısı - YerelScript

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function onEventFire(passedTable)
for k, v in passedTable do
print(typeof(k)) --> dizi
end
end
-- İşlevi etkinliğe bağla
remoteEvent.OnClientEvent:Connect(onEventFire)
Etkinlik Ateşleme - Kod

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local Workspace = game:GetService("Workspace")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- Gelen oyuncuları dinleyin ve her birine uzaktan olay gönderin
local function onPlayerAdded(player)
remoteEvent:FireClient(player,
{
[Workspace.Baseplate] = true
}
)
end
Players.PlayerAdded:Connect(onPlayerAdded)

Geçmiş işlevler

Bir veya için argüman olarak dahil edilen işlevler, client-server sınırı boyunca yeniden yapılmayacak ve bu nedenle işlevleri uzaktan geçirmek imkansız hale gelecek.Bunun yerine, alınan taraftaki sonuç argümanı olacak nil .

Etkinlik Bağlantısı - YerelScript

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function onClientEvent(func)
print(func) --> nulsüz
end
remoteEvent.OnClientEvent:Connect(onClientEvent)
Etkinlik Ateşleme - Kod

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function testFunction()
print("Hello world!")
end
-- İşlev olarak bir argüman olarak uzaktan etkinlik ateşle
remoteEvent:FireAllClients(testFunction)

Tablo indeksleme

Bir veri tablosu geçerseniz, karışık bir sayı ve dize anahtar tablosu geçirmeyin.Bunun yerine, tümüyle anahtar-değer çiftlerinden (sözlük) veya sayısal indekslerden tümüyle oluşan bir tablo geçin.

Etkinlik Bağlantısı - Kod

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function onEventFire(player, passedTable)
for k, v in passedTable do
print(k .. " = " .. v)
--> 1 = Kılıç
--> 2 = Yay
--> CharName = Diva Dragonslayer'ı
--> CharClass = Düzenbaz
end
end
-- İşlevi etkinliğe bağla
remoteEvent.OnServerEvent:Connect(onEventFire)
Etkinlik ateşleme - Yerel Kod

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- Sayısal indeksli tablo
local inventoryData = {
"Sword", "Bow"
}
-- Dizin tablosu
local characterData = {
CharName = "Diva Dragonslayer",
CharClass = "Rogue"
}
remoteEvent:FireServer(inventoryData)
remoteEvent:FireServer(characterData)

Tablo kimlikleri

Uzaktaki olaylara/çağrılara argüman olarak geçen tablolar kopyalanır, yani olayı ateşlemek veya çağrıyı yapmak sırasında sağlananlarla aynı olmayacaklar.Ayrıca, geri verilen masaların invokatöre sağlananlara eşit olması da garanti edilmez.Bunu şu kodu bir RemoteFunction üzerinde çalıştırarak ve tablo kimliklerinin nasıl farklı olduğunu gözlemleyerek gösterabilirsiniz.

Geri Çağırma Bağlantısı - Kod

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteFunction = ReplicatedStorage:FindFirstChildOfClass("RemoteFunction")
-- Geri çağırma işlevi
local function returnTable(player, passedTable)
-- Çağrı sırasında çıktı tablosu kimliği
print(tostring(passedTable)) --> tablo: 0x48eb7aead27563d9
return passedTable
end
-- İşlevi uzaktaki işlevin geri çağrısı olarak ayarla
remoteFunction.OnServerInvoke = returnTable
Etkinlik Daveti - Yerel Kod

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteFunction = ReplicatedStorage:FindFirstChildOfClass("RemoteFunction")
local inventoryData = {
"Sword", "Bow"
}
-- Orijinal tablo kimliğini çıkart
print(tostring(inventoryData)) --> tablo: 0x059bcdbb2b576549
local invokeReturn = remoteFunction:InvokeServer(inventoryData)
-- Döndürme sırasında çıktı tablosu kimliği
print(tostring(invokeReturn)) --> table: 0x9fcae7919563a0e9

Met tabloları

Bir tablonun bir metatablosu varsa, tüm metatablo bilgileri transferde kaybolur.Aşağıdaki kod örneğinde, NumWheels özelliği Car metatable'in bir parçasıdır.Sunucu aşağıdaki tabloyu aldığında, tablosu özelliğine sahiptir, ancak değil özelliği.

Etkinlik Bağlantısı - Kod

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function onEvent(player, param)
print(param) --> { ["İsim"] = "MyTruck"}
end
-- İşlevi etkinliğe bağla
remoteEvent.OnServerEvent:Connect(onEvent)
Etkinlik ateşleme - Yerel Kod

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local Car = {}
Car.NumWheels = 4
Car.__index = Car
local truck = {}
truck.Name = "MyTruck"
setmetatable(truck, Car)
-- Bir metatable içeren masa ile ateş etkinliği
remoteEvent:FireServer(truck)

Tekrarlanmayan örnekler

Bir RemoteEvent veya RemoteFunction bir gönderene sadece görünen bir değer geçirirse, Roblox bunu istemci-sunucu sınırı boyunca yeniden yazmaz ve değer yerine nil geçer.Örneğin, bir Script ın bir ServerStorage 'in torununu geçmesi durumunda, olayı dinleyen istemci o nesne için yeniden yapılamaz olduğundan dolayı bir nil değeri alacaktır, çünkü bu nesne istemci için yeniden yapılamaz.

Etkinlik Ateşleme - Kod

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerStorage = game:GetService("ServerStorage")
local Players = game:GetService("Players")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- Müşterinin ServerStorage'a erişemediği için "sıfır" olarak alınacak çünkü müşteri depolama alanına erişemez
local storedPart = Instance.new("Part")
storedPart.Parent = ServerStorage
local function onPlayerAdded(player)
remoteEvent:FireClient(player, storedPart)
end
Players.PlayerAdded:Connect(onPlayerAdded)

Benzer şekilde, bir parçayı bir LocalScript 'de oluşturup bunu bir Script 'a geçmeye çalışırsanız, sunucu parçanın sunucu için yeniden üretilemez olduğundan dolayı nil görecektir çünkü parça sunucu için yeniden üretilemez.

Etkinlik ateşleme - Yerel Kod

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Workspace = game:GetService("Workspace")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- Sunucu bu parçayı bilmediğinden "sıfır" olarak alınacaktır
local clientPart = Instance.new("Part")
clientPart.Parent = Workspace
remoteEvent:FireServer(clientPart)