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:

text
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:

lua
-- server
ESX.RegisterServerCallback('my_script:getMoney', function(source, cb)
    local xPlayer = ESX.GetPlayerFromId(source)
    cb(xPlayer.getMoney())
end)
lua
-- 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:

lua
-- 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)
lua
-- 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:

lua
-- server
lib.callback.register('my_script:getMoney', function(source)
    local xPlayer = ESX.GetPlayerFromId(source)
    return xPlayer.getMoney()
end)
lua
-- 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:

lua
local ok = lib.callback.await('my_script:buy', false, 'burger', 2)
lua
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:

lua
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:

  1. 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.
  2. 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.
  3. Cevaptan önce sunucuda bir hata. Sunucu işlevi hata verirse, örneğin xPlayer nil ise, cevap hiçbir zaman gönderilmez. Sunucu konsolunu kontrol edin, istemci konsolunu değil.
  4. Her yolu cb çağırmayı asla ESX ve QBCore'da, cb(...) çağırmadan dönen şube istemciyi beklemeyi bırakır:
lua
-- 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)
lua
-- right
ESX.RegisterServerCallback('my_script:getJob', function(source, cb)
    local xPlayer = ESX.GetPlayerFromId(source)
    cb(xPlayer and xPlayer.job.name or nil)
end)
  1. ox_lib'de return'ü unuttunuz. lib.callback.register işlevi return'ü olmadan nil'e cevap verir.
  2. Ç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.
  3. Karışık stiller. lib.callback.register ile kaydedilen callback ESX.TriggerServerCallback ile ç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 print ekleyin. Basılı hiçbir şey 1 veya 2 adımları anlamına gelir, cevap olmadan basılı 3 ila 5 anlamına gelir.

İstemcide nil karşı koruma

Cevabı eksik olabilecek bir şey olarak işleyin:

lua
local money = lib.callback.await('my_script:getMoney', false)
if not money then
    return print('No answer from the server')
end

Eski çerçeveler için, endeksleri yapmadan önce argümanı kontrol edin:

lua
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.callback değ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.

Bu sorunu yaşatmayan scriptler

Advanced BoostingTabletten araç boosting: D’den S+ sınıfına kontratlar, ekipler ve canlı sıra.Scripti gör →Quest CreatorGörevler ve NPC diyalogları için oyun içinde düğüm düğüm kurulan görsel editör.Scripti gör →Pawn Shop Applb-phone içinde oyuncudan oyuncuya rehin pazarı.Scripti gör →

Okumaya devam edin