Sunucu callback'i nil döndürür: ESX, QBCore ve ox_lib callback'leri
ESX.TriggerServerCallback, QBCore TriggerCallback ve lib.callback.await nil döndürüyor mu? Her callback'inin sunucu ve istemcide nasıl çalıştığı ve hiçbir şey döndürmeme nedenleri.
Bir istemci betiği sunucudan veri ister ve geri gelen nil'dir veya hiç bir şey değildir:
SCRIPT ERROR: @my_script/client/main.lua:21: attempt to index a nil value (local 'result')Sunucu geri çağırmaları, istemcinin sunucuya bir soru sorması ve cevap almasıdır. Her çerçevenin kendisi vardır ve ox_lib'in her yerde çalışan bir vardır. Bu makale üçünü ve neden nil döndürüyorlar gösterir.
ESX
Sunucuya kaydedin, istemciden tetikleyin:
-- server
ESX.RegisterServerCallback('my_script:getMoney', function(source, cb)
local xPlayer = ESX.GetPlayerFromId(source)
cb(xPlayer.getMoney())
end)-- client
ESX.TriggerServerCallback('my_script:getMoney', function(money)
print(money)
end)Sunucu işlevi source ve cb alır ve cevabı cb'ye geçirirsiniz. İstemciden ekstra argümanlar cb sonrasında gelir. İstemci işlevi cb'nin gönderdiğini alır.
QBCore
Adlar farklı, şekil aynıdır:
-- server
local QBCore = exports['qb-core']:GetCoreObject()
QBCore.Functions.CreateCallback('my_script:getMoney', function(source, cb)
local Player = QBCore.Functions.GetPlayer(source)
cb(Player.PlayerData.money.cash)
end)-- client
local QBCore = exports['qb-core']:GetCoreObject()
QBCore.Functions.TriggerCallback('my_script:getMoney', function(money)
print(money)
end)Betik içinde ESX veya QBCore nil ise, callback hiçbir zaman kayıtlı değildir. Bkz. ESX is nil ve QBCore is nil.
ox_lib
ox_lib geri çağırmaları bir çerçeveye gerek duymaz ve cevap cb işlevi yerine bir dönüş değeridir:
-- server
lib.callback.register('my_script:getMoney', function(source)
local xPlayer = ESX.GetPlayerFromId(source)
return xPlayer.getMoney()
end)-- client
local money = lib.callback.await('my_script:getMoney', false)
print(money)await'in ikinci argümanı, çağrı ve cevap arasında milisaniye cinsinden bir gecikmedir (false hiçbiri için). Sunucu için argümanlar onu izler:
local ok = lib.callback.await('my_script:buy', false, 'burger', 2)lib.callback.register('my_script:buy', function(source, item, amount)
-- ...
return true
end)Callback'inin var olması için, betik ox_lib'i manifest'te yükler:
shared_script '@ox_lib/init.lua'Olmadan, lib nil'dir: bkz. ox_lib init.lua not found.
Sunucu ayrıca istemciyi çağırabilir: sunucuda lib.callback.await('name', playerId, ...) ile lib.callback.register istemcide. Beklemeyi tercih etmezseniz, lib.callback('name', false, function(result) end) bunun yerine bir işlevi alır.
Callback'i neden nil döndürür
Neredeyse her durum bunlardan birisidir:
- Ad eşleşmez. Kayıt ve tetikleyici adlar büyük harf dahil olmak üzere aynı olmalıdır. Yazım hatası fark edileceği hata yükseltmez, sadece hiç cevap vermez.
- Kayıtlı değil. Sunucu dosyası hiçbir zaman çalışmadı:
server_scripts'den eksik, kaynak başlamadı veya kayıt satırına ulaşmadan önce başarısız oldu. - Cevaptan önce sunucuda bir hata. Sunucu işlevi hata verirse, örneğin
xPlayernil ise, cevap hiçbir zaman gönderilmez. Sunucu konsolunu kontrol edin, istemci konsolunu değil. - Her yolu
cbçağırmayı asla ESX ve QBCore'da,cb(...)çağırmadan dönen şube istemciyi beklemeyi bırakır:
-- wrong: no cb when the player is missing
ESX.RegisterServerCallback('my_script:getJob', function(source, cb)
local xPlayer = ESX.GetPlayerFromId(source)
if xPlayer then
cb(xPlayer.job.name)
end
end)-- right
ESX.RegisterServerCallback('my_script:getJob', function(source, cb)
local xPlayer = ESX.GetPlayerFromId(source)
cb(xPlayer and xPlayer.job.name or nil)
end)- ox_lib'de
return'ü unuttunuz.lib.callback.registerişlevireturn'ü olmadannil'e cevap verir. - Çok erken çağırırsınız. Betik başında tetiklenen istemci callback'i sunucuya ulaşabilir, örneğin yeniden başlattıktan sonra, kaydedilmeden önce. Oyuncu yüklendikten sonra tetikleyin.
- Karışık stiller.
lib.callback.registerile kaydedilen callbackESX.TriggerServerCallbackile çağrılamaz. Eşleşen çifti kullanın.
İpucu: hangi durumunuz olduğunu bulmak için sunucu işlevinin ilk satırı olarak bir
İstemcide nil karşı koruma
Cevabı eksik olabilecek bir şey olarak işleyin:
local money = lib.callback.await('my_script:getMoney', false)
if not money then
return print('No answer from the server')
endEski çerçeveler için, endeksleri yapmadan önce argümanı kontrol edin:
QBCore.Functions.TriggerCallback('my_script:getJob', function(job)
if not job then return end
print(job)
end)Hangisini kullanmalı
- Yalnızca bir çerçeve için yazma: kendisinin geri araması iyidir.
- Birçok çerçeve için yazma veya QBox için: ox_lib kullanın, böylece bir callback her yerde çalışır.
- Yeni kod yazma:
lib.callbackdeğer döndürür ve normal bir işlev gibi okudu, hataların tespit edilmesini kolaylaştırır.
Bir betiği ESX ile QBCore arasında taşıyorsanız, callback adları function map bölümünde bir satırdır.
Kontrol listesi
| Belirtisi | Çözüm |
|---|---|
| Sonuç nil | Adın her iki tarafta tam eşleşip eşleşmediğini kontrol edin |
| Hiçbir zaman cevap vermez | Sunucu dosyasının manifest'te ve kaynağın başladığını emin olun |
| Sunucu konsolunda hata | Düzeltmeyin; başarısız bir callback hiçbir cevap göndermez |
| ESX veya QBCore: bazı yollarda cevap yok | cb(...) her şubesinde çağırın |
| ox_lib: nil sonuç | lib.callback.register işlevine return ekleyin |
lib nil |
Manifest'e shared_script '@ox_lib/init.lua' ekleyin |
Kısa yanıtlar
Callback ile olay arasındaki fark nedir?
Olay ileti gönderir ve cevap beklemiyor. Callback diğer tarafa sorar ve bir değer geri alır, bu nedenle istemci yalnızca sunucunun bildiği verileri kullanabilir.
ESX veya QBCore'da ox_lib callback'lerini kullanabilir miyim?
Evet. ox_lib çerçeveden bağımsızdır, bu nedenle lib.callback ox_lib başlatıldığı ve betik tarafından yüklü olduğu sürece ESX, QBCore ve QBox'ta çalışır.
lib.callback.await neden betiğimi bir süre durdurursa?
Sunucunun cevabını bekler, bu nedenle iş parçacığını verir. Sunucu callback'i eksik veya hata verirse hiç cevap vermez, iş parçacığı beklemeye devam eder veya bir hata ile başarısız olur.


