Sự kiện và cuộc gọi trả lại từ xa

*Nội dung này được dịch bằng AI (Beta) và có thể có lỗi. Để xem trang này bằng tiếng Anh, hãy nhấp vào đây.

Các trải nghiệm Roblox mặc định là nhiều người chơi, vì vậy tất cả các trải nghiệm tự nhiên giao tiếp giữa máy chủ và các khách hàng kết nối của người chơi.Trong trường hợp đơn giản nhất, khi người chơi di chuyển nhân vật của họ, một số Humanoid tính năng, chẳng hạn như trạng thái, được gửi đến máy chủ, điều này truyền thông tin này đến các khách hàng kết nối khác.

Sự kiện và cuộc gọi từ xa cho phép bạn giao tiếp theo giới hạn khách hàng-máy chủ:

  • RemoteEvents bật giao tiếp một chiều (gửi yêu cầu và không để có được phản hồi).
  • UnreliableRemoteEvents bật giao tiếp một chiều cho dữ liệu thay đổi liên tục hoặc không quan trọng đối với trạng thái trò chơi.Các sự kiện này trao đổi lệnh và độ tin cậy để cải thiện hiệu hiệu lựcmạng.
  • RemoteFunctions bật kết nối hai chiều (gửi yêu cầu và chờ đợi cho đến khi nhận được phản hồi từ người nhận).

Không giống như sự kiện có thể gắn kết, có công dụng giới hạn hơn, các trường hợp sử dụng cho sự kiện và chức năng từ xa quá nhiều để liệt kê:

  • Trò chơi - trải nghiệm trò chơicơ bản, chẳng hạn như một người chơi đạt đến cuối của một cấp, có thể yêu cầu một sự kiện từ xa.Một kịch bản khách thông báo cho máy chủ, và các kịch bản máy chủ đặt lại vị trí của người chơi.
  • Xác minh máy chủ - Nếu một người chơi cố gắng uống một thuốc, họ có thực sự thuốc đó? Để đảm bảo công bằng, máy chủ phải là nguồn sự thật cho một trải nghiệm.Một kịch bản khách hàng có thể sử dụng sự kiện remote để thông báo cho máy chủ rằng người chơi đang uống một loại thuốc, và sau đó các kịch bản máy chủ có thể quyết định xem người chơi có thực sự có loại thuốc đó hay không và có nên cung cấp bất kỳ lợi ích nào không.
  • Cập nhật giao diện người dùng - Khi tình trạng trò chơi thay đổi, các kịch bản máy chủ có thể sử dụng sự kiện remote để thông báo cho khách hàng về các thay đổi về điểm số, mục tiêu, v.v.
  • Mua trên Thị trường trong trải nghiệm - Đối với ví dụ thực hiện sử dụng chức năng remote, xem Mua đăng ký nhanh.

Tham khảo nhanh

Các bảng sau đây phục vụ như một tham khảo nhanh về cách sử dụng RemoteEventsRemoteFunctions để giao tiếp giữa khách hàng và máy chủ.

Khách hàng → Máy chủ >
Khách hàngRemoteEvent:FireServer(args)
Máy chủRemoteEvent.OnServerEvent:Connect(function(player, args))
Máy chủ → Khách hàng >
Máy chủRemoteEvent:FireClient(player, args)
Khách hàngRemoteEvent.OnClientEvent:Connect(function(args))
Máy chủ → Tất cả các khách hàng >
Máy chủRemoteEvent:FireAllClients(args)
Khách hàngRemoteEvent.OnClientEvent:Connect(function(args))

Sự kiện từ xa

Một đối tượng RemoteEvent giúp dễ dàng giao tiếp không đồng bộ, một chiều qua ranh giới khách-máy chủ mà không cần phải đổi lấy một phản hồi.

Để tạo một cửa sổ mới RemoteEvent qua cửa sổ Explorer trong Studio:

  1. Di chuột qua thùng chứa mà bạn muốn chèn RemoteEvent .Để đảm bảo cả máy chủ và khách hàng truy cập, nó phải ở trong một nơi mà cả hai bên có thể nhìn thấy nó, chẳng hạn như ReplicatedStorage , mặc dù trong một số trường hợp thích hợp để lưu nó trong Workspace hoặc bên trong một Tool .
  2. Nhấp vào nút xuất hiện bên phải tên của thùng chứa và chèn một ví ví dụ / trường hợp Sự kiện từ xa .
  3. Đổi tên instance để mô tả mục đích của nó.

Một khi bạn đã tạo ra một RemoteEvent , nó có thể thúc đẩy giao tiếp một chiều từ khách hàng đến máy chủ , từ máy chủ đến khách hàng , hoặc từ máy chủ đến tất cả khách hàng .

Khách hàng → Máy chủ

Máy chủ → Khách hàng
>

Máy chủ → Tất cả khách hàng
>

Client → máy chủ

Bạn có thể sử dụng một để kích hoạt một sự kiện trên máy chủ bằng cách gọi phương pháp trên một .Nếu bạn truyền các tham số cho FireServer() , chúng sẽ được chuyển đến người xử lý sự kiện trên máy chủ với một số giới hạn nhất định .Lưu ý rằng tham số đầu tiên của người xử lý sự kiện trên máy chủ luôn là đối tượng Player của khách hàng gọi nó, và các tham số bổ sung theo theo dõi.

Khách hàngRemoteEvent:FireServer(args)
Máy chủRemoteEvent.OnServerEvent:Connect(function(player, args))

Các kết nối sau đây Script kết nối một xử lý sự kiện với OnServerEvent tạo ra một Part mới trên máy chủ.Các thành phần đi kèm LocalScript sau đó gọi FireServer() trên RemoteEvent instance với ColorPosition mong muốn cho phần.

Kết Nối Sự Kiện - Tập lệnh

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Workspace = game:GetService("Workspace")
-- Nhận tham chiếu đến ví ví dụ / trường hợpsự kiện từ xa
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
-- Kết nối chức năng với sự kiện
remoteEvent.OnServerEvent:Connect(onCreatePart)
Bắn sự kiện - LocalScript

local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Nhận tham chiếu đến ví ví dụ / trường hợpsự kiện từ xa
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- Bắn sự kiện remote và truyền thêm các tham số
remoteEvent:FireServer(Color3.fromRGB(255, 0, 0), Vector3.new(0, 25, -20))

Máy chủ → khách hàng

Bạn có thể sử dụng một để kích hoạt một sự kiện trên một khách hàng bằng cách gọi phương pháp trên một .Argent đầu tiên cho là đối tượng của khách hàng mà bạn muốn đáp lại sự kiện, và các argent bổ sung được chuyển đến khách hàng với một số giới hạn nhất định .Lưu ý rằng người xử lý sự kiện không cần bao gồm đối tượng Player như là lập luận đầu tiên vì bạn có thể xác định người chơi trên máy khách với Players.LocalPlayer .

Máy chủRemoteEvent:FireClient(player, args)
Khách hàngRemoteEvent.OnClientEvent:Connect(function(args))

Các kết nối sau LocalScript kết nối một xử lý sự kiện với sự kiện OnClientEvent .The accompanying Script sau đó lắng nghe các người chơi đến máy chủ và gọi FireClient() cho mỗi với dữ liệu ngẫu nhiên.

Kết Nối Sự Kiện - LocalScript

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
-- Nhận tham chiếu đến ví ví dụ / trường hợpsự kiện từ xa
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
-- Kết nối chức năng với sự kiện
remoteEvent.OnClientEvent:Connect(onNotifyPlayer)
Bắn sự kiện - Tập lệnh

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
-- Nhận tham chiếu đến ví ví dụ / trường hợpsự kiện từ xa
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- Lắng nghe người chơi nhận được và phát sự kiện remote đến mỗi
local function onPlayerAdded(player)
print("[Server] Firing event to player", player.Name)
remoteEvent:FireClient(player, Players.MaxPlayers, Players.RespawnTime)
end
Players.PlayerAdded:Connect(onPlayerAdded)

Máy chủ → tất cả khách hàng

Bạn có thể sử dụng một Script để kích hoạt một sự kiện trên tất cả các khách hàng bằng cách gọi phương pháp FireAllClients() trên một RemoteEvent .Không giống như FireClient() , phương pháp FireAllClients() không yêu cầu một đối tượng Player vì nó bắn RemoteEvent cho tất cả các khách hàng.

Máy chủRemoteEvent:FireAllClients(args)
Khách hàngRemoteEvent.OnClientEvent:Connect(function(args))

Các kết nối sau đây LocalScript kết nối một xử lý sự kiện với sự kiện OnClientEvent còn lại có thời gian đếm ngược còn lại.The accompanying Script sau đó gọi FireAllClients() trong một vòng lặp mỗi giây để bắn RemoteEvent cho tất cả các khách hàng.

Kết Nối Sự Kiện - LocalScript

local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Nhận tham chiếu đến ví ví dụ / trường hợpsự kiện từ xa
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function onTimerUpdate(seconds)
print(seconds)
end
-- Kết nối chức năng với sự kiện
remoteEvent.OnClientEvent:Connect(onTimerUpdate)
Bắn sự kiện - Tập lệnh

local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Nhận tham chiếu đến ví ví dụ / trường hợpsự kiện từ xa
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local countdown = 5
-- Bắn sự kiện remote mỗi giây cho đến khi hết thời gian
for timeRemaining = -1, countdown do
remoteEvent:FireAllClients(countdown - timeRemaining)
task.wait(1)
end

Gọi lại từ xa

Một đối tượng RemoteFunction giúp dễ dàng giao tiếp song song, hai chiều qua ranh giới khách-máy chủ.Người gửi của một chức năng remote sẽ tiếp tục cho đến khi nó nhận được một phản hồi từ người nhận.

Để tạo một cửa sổ mới RemoteFunction qua cửa sổ Explorer trong Studio:

  1. Di chuột qua thùng chứa mà bạn muốn chèn RemoteFunction .Để đảm bảo cả máy chủ và khách hàng truy cập, nó phải ở trong một nơi mà cả hai bên có thể nhìn thấy nó, chẳng hạn như ReplicatedStorage , mặc dù trong một số trường hợp thích hợp để lưu nó trong Workspace hoặc bên trong một Tool .
  2. Nhấp vào nút xuất hiện bên phải tên của thùng chứa và chèn một ví ví dụ / trường hợp RemoteFunction .
  3. Đổi tên instance để mô tả mục đích của nó.

Một khi bạn đã tạo một RemoteFunction , nó có thể thúc đẩy giao tiếp hai chiều giữa khách hàng và máy chủ hoặc giữa máy chủ và khách hàng .

Khách hàng → Máy chủ → Khách hàng

Máy chủ → Khách hàng → Máy chủ
>

Client → máy chủ → client

Bạn có thể sử dụng một LocalScript để gọi một chức năng trên máy chủ bằng cách gọi phương pháp InvokeServer() trên một RemoteFunction .Không giống như một sự kiện remote , sự kiện được gọi bởi cho đến khi callback trả về.Các tham số mà bạn chuyển cho > chuyển đến > callback của > với một số giới hạn nhất định .Lưu ý rằng nếu bạn xác định nhiều cuộc gọi lại cho cùng một RemoteFunction , chỉ có định nghĩa cuối cùng được thực hiện.

Khách hàngRemoteFunction:InvokeServer(args)
Máy chủRemoteFunction.OnServerInvoke = function(player, args)

Các định nghĩa sau Script xác định chức năng trả lại qua OnServerInvoke và trả lại yêu cầu Part thông qua giá trị return của nó.The accompanying LocalScript sau đó gọi InvokeServer() với tham số bổ sung xác định màu và vị trí phần được yêu cầu.

Kết Nối Trả Lại - Tập Lệnh

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Workspace = game:GetService("Workspace")
-- Nhận tham chiếu đến ví dụ ví dụ / trường hợpnăng được gọi từ xa
local remoteFunction = ReplicatedStorage:FindFirstChildOfClass("RemoteFunction")
-- Chức năng gọi lại
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
-- Đặt chức năng làm callback của chức năng từ xa
remoteFunction.OnServerInvoke = createPart
Lời mời sự kiện - LocalScript

local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Nhận tham chiếu đến ví dụ ví dụ / trường hợpnăng được gọi từ xa
local remoteFunction = ReplicatedStorage:FindFirstChildOfClass("RemoteFunction")
-- Truyền một màu và vị trí khi gọi lại công cụ
local newPart = remoteFunction:InvokeServer(Color3.fromRGB(255, 0, 0), Vector3.new(0, 25, -20))
-- Xuất tham chiếu phần đã trả về
print("The server created the requested part:", newPart)

Server → khách hàng → máy chủ

Bạn có thể sử dụng một Script để gọi một chức năng trên khách hàng bằng cách gọi phương pháp InvokeClient() trên một RemoteFunction, nhưng nó có những rủi ro nghiêm trọng như sau:

  • Nếu khách hàng ném một lỗi, máy chủ cũng ném lỗi.
  • Nếu khách hàng kết nối lại trong khi đang được gọi, InvokeClient() ném một lỗi.
  • Nếu khách hàng không trả lại giá trị, máy chủ sẽ mãi mãi cung cấp.

Đối với các hành động không yêu cầu giao tiếp hai chiều, chẳng hạn như cập nhật GUI, sử dụng một RemoteEvent và truyền thông từ máy chủ đến khách hàng .

Giới hạn các tham số

Khi bạn khai hỏa một RemoteEvent hoặc gọi một RemoteFunction , nó chuyển tiếp bất kỳ tham số nào bạn truyền với sự kiện hoặc đến chức năng gọi lại.Bất kỳ loại đối tượng Roblox nào như một Enum , Instance , hoặc khác có thể được truyền, cũng như các loại Luau như số, chuỗi và boolean, mặc dù bạn nên cẩn thận khám phá các hạn chế sau.

Chỉ mục không phải chuỗi

Nếu bất kỳ chỉ mục của một bảng đã truyền qua là kiểu không chuỗi như Instance , dữ liệu người dùng hoặc chức năng , Roblox tự động chuyển các chỉ mục này thành chuỗi.

Kết Nối Sự Kiện - LocalScript

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function onEventFire(passedTable)
for k, v in passedTable do
print(typeof(k)) --> chuỗi
end
end
-- Kết nối chức năng với sự kiện
remoteEvent.OnClientEvent:Connect(onEventFire)
Bắn sự kiện - Tập lệnh

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local Workspace = game:GetService("Workspace")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- Lắng nghe người chơi nhận được và phát sự kiện remote đến mỗi
local function onPlayerAdded(player)
remoteEvent:FireClient(player,
{
[Workspace.Baseplate] = true
}
)
end
Players.PlayerAdded:Connect(onPlayerAdded)

Chức năng đã truyền qua

Các chức năng bao gồm như là tham số cho một RemoteEvent hoặc RemoteFunction sẽ không được sao chép trên ranh giới khách-máy chủ, làm cho không thể truyền chức năng từ xa.Thay vào đó, các tham số kết quả ở phía nhận sẽ là nil .

Kết Nối Sự Kiện - LocalScript

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function onClientEvent(func)
print(func) --> không
end
remoteEvent.OnClientEvent:Connect(onClientEvent)
Bắn sự kiện - Tập lệnh

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function testFunction()
print("Hello world!")
end
-- Sự kiện điều khiển lửa với chức năng là một tham số
remoteEvent:FireAllClients(testFunction)

Lập chỉ mục bảng

Nếu bạn truyền một bảng dữ liệu, đừng truyền một bảng trộn các chìa khóa số và chuỗi.Thay vào đó, truyền một bảng bao gồm hoàn toàn các cặp chìa khóa-giá trị (từ điển) hoặc hoàn toàn các chỉ mục số.

Kết Nối Sự Kiện - Tập lệnh

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 = Kiếm
--> 2 = Cung tên
--> Tên CharName = Diva Dragonslayer
--> CharClass = Kẻ lừa đảo
end
end
-- Kết nối chức năng với sự kiện
remoteEvent.OnServerEvent:Connect(onEventFire)
Bắn sự kiện - LocalScript

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- Bảng được đánh số theo thứ tự
local inventoryData = {
"Sword", "Bow"
}
-- Bảng từ điển
local characterData = {
CharName = "Diva Dragonslayer",
CharClass = "Rogue"
}
remoteEvent:FireServer(inventoryData)
remoteEvent:FireServer(characterData)

Nhận dạng bảng

Các bảng được chuyển đến làm tham số cho sự kiện/cuộc gọi từ xa được sao chép, có nghĩa là chúng sẽ không tương đương chính xác với những gì được cung cấp khi bắn sự kiện hoặc kích hoạt cuộc gọi trả lời.Các bảng được trả lại cho người gọi cũng sẽ không tương đương chính xác với những gì được cung cấp.Bạn có thể minh chứng điều này bằng cách chạy lệnh sau trên một RemoteFunction và quan sát cách các danh xưng bảng khác nhau.

Kết Nối Trả Lại - Tập Lệnh

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteFunction = ReplicatedStorage:FindFirstChildOfClass("RemoteFunction")
-- Chức năng gọi lại
local function returnTable(player, passedTable)
-- Xuất ID bảng trên lời gọi
print(tostring(passedTable)) --> bảng: 0x48eb7aead27563d9
return passedTable
end
-- Đặt chức năng làm callback của chức năng từ xa
remoteFunction.OnServerInvoke = returnTable
Lời mời sự kiện - LocalScript

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteFunction = ReplicatedStorage:FindFirstChildOfClass("RemoteFunction")
local inventoryData = {
"Sword", "Bow"
}
-- Xuất ID bảng gốc
print(tostring(inventoryData)) --> bảng: 0x059bcdbb2b576549
local invokeReturn = remoteFunction:InvokeServer(inventoryData)
-- Nhận dạng bảng xuất ra khi trở lại
print(tostring(invokeReturn)) --> table: 0x9fcae7919563a0e9

Bảng biểu Metatables

Nếu một bảng có một metatable, tất cả thông tin metatable được mất trong quá trình chuyển.Trong ví dụ mã sau, thuộc tính NumWheels là một phần của Car bảng truyền đạt.Khi máy chủ nhận được bảng sau, bảng truck có tính chất Name nhưng không tính chất NumWheels.

Kết Nối Sự Kiện - Tập lệnh

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
local function onEvent(player, param)
print(param) --> { ["Tên"] = "MyTruck"]
end
-- Kết nối chức năng với sự kiện
remoteEvent.OnServerEvent:Connect(onEvent)
Bắn sự kiện - LocalScript

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)
-- Sự kiện lửa với bảng bao gồm một metatable
remoteEvent:FireServer(truck)

Các ví dụ không được sao chép

Nếu một RemoteEvent hoặc RemoteFunction truyền một giá trị chỉ có thể nhìn thấy được với người gửi, Roblox không sao chép nó trên ranh giới khách-máy chủ và thay thế bằng giá trị nil thay vì giá trị.Ví dụ, nếu một Script truyền một con cháu của ServerStorage , khách hàng lắng nghe sự kiện sẽ nhận được một giá trị nil bởi vì đối tượng đó không thể sao chép cho khách hàng.

Bắn sự kiện - Tập lệnh

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerStorage = game:GetService("ServerStorage")
local Players = game:GetService("Players")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- Sẽ được nhận như "không" bởi vì khách hàng không thể truy cập ServerStorage
local storedPart = Instance.new("Part")
storedPart.Parent = ServerStorage
local function onPlayerAdded(player)
remoteEvent:FireClient(player, storedPart)
end
Players.PlayerAdded:Connect(onPlayerAdded)

Tương tự, nếu bạn tạo một phần trong một LocalScript và thử chuyển nó cho một Script , máy chủ sẽ thấy nil vì phần không thể sao chép cho máy chủ.

Bắn sự kiện - LocalScript

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Workspace = game:GetService("Workspace")
local remoteEvent = ReplicatedStorage:FindFirstChildOfClass("RemoteEvent")
-- Sẽ được nhận như "không" vì máy chủ không biết về phần này
local clientPart = Instance.new("Part")
clientPart.Parent = Workspace
remoteEvent:FireServer(clientPart)