Server Callback gibt nil zurück: ESX, QBCore und ox_lib Callbacks

ESX.TriggerServerCallback, QBCore TriggerCallback und lib.callback.await geben nil zurück? Wie jeder Callback auf dem Server und Client funktioniert, und die Gründe, warum sie nichts zurückgeben.

Ein Client-Script fragt den Server nach Daten, und was zurückkommt ist nil, oder überhaupt nichts:

text
SCRIPT ERROR: @my_script/client/main.lua:21: attempt to index a nil value (local 'result')

Server-Callbacks sind, wie der Client den Server eine Frage stellt und eine Antwort bekommt. Jedes Framework hat sein eigenes, und ox_lib hat einen, der überall funktioniert. Dieser Artikel zeigt die drei und warum sie nil zurückgeben.

ESX

Registriere auf dem Server, triggere vom Client:

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)

Die Server-Funktion bekommt source und cb, und du übergibst die Antwort an cb. Extra-Argumente vom Client kommen nach cb. Die Client-Funktion erhält, was cb gesendet hat.

QBCore

Die Namen unterscheiden sich, die Form ist gleich:

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)

Wenn ESX oder QBCore nil in dem Script ist, wird der Callback nie registriert. Siehe ESX ist nil und QBCore ist nil.

ox_lib

ox_lib Callbacks brauchen kein Framework, und die Antwort ist ein Rückgabewert anstelle einer cb Funktion:

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)

Das zweite Argument von await ist eine Verzögerung in Millisekunden zwischen dem Aufruf und der Antwort (verwende false für keine). Argumente für den Server folgen ihm:

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)

Damit der Callback existiert, lädt das Script ox_lib in sein Manifest:

lua
shared_script '@ox_lib/init.lua'

Ohne es ist lib nil: siehe ox_lib init.lua nicht gefunden.

Der Server kann auch einen Client aufrufen: lib.callback.await('name', playerId, ...) auf dem Server, mit lib.callback.register auf dem Client. Wenn du bevorzugst nicht zu warten, nimmt lib.callback('name', false, function(result) end) eine Funktion.

Warum ein Callback nil zurückgibt

Fast jeden Fall ist einer von diesen:

  1. Der Name stimmt nicht überein. Die Register- und Trigger-Namen müssen identisch sein, einschließlich Groß-/Kleinschreibung. Ein Tippfehler wirft keinen Fehler, den du bemerken wirst, antwortet einfach nie.
  2. Es ist nicht registriert. Die Server-Datei wurde nie ausgeführt: sie fehlt in server_scripts, die Ressource startete nicht, oder sie schlug fehl, bevor sie die Register-Zeile erreichte.
  3. Ein Fehler auf dem Server, vor der Antwort. Wenn die Server-Funktion einen Fehler hat, zum Beispiel xPlayer ist nil, wird die Antwort nie gesendet. Überprüfe die Server-Konsole, nicht die Client-Konsole.
  4. Du rufst cb nie auf jedem Pfad auf. Auf ESX und QBCore hinterlässt ein Zweig, der ohne cb(...) aufzurufen zurückgegeben wird, den Client, der wartet:
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. Du hast return bei ox_lib vergessen. Eine lib.callback.register Funktion, die kein return hat, antwortet mit nil.
  2. Du rufst zu früh an. Ein Client-Callback, der beim Script-Start ausgelöst wird, kann den Server erreichen, bevor sein Register lief, nach einem Neustart zum Beispiel. Trigger es nach, dass der Spieler geladen hat.
  3. Gemischte Stile. Ein Callback, der mit lib.callback.register registriert ist, kann nicht mit ESX.TriggerServerCallback aufgerufen werden. Verwende das passende Paar.

Tipp: Um herauszufinden, welchen Fall du hast, füge ein print als erste Zeile der Server-Funktion ein. Kein Print bedeutet Schritte 1 oder 2, ein Print ohne Antwort bedeutet 3 bis 5.

Schütze dich gegen nil auf dem Client

Behandle die Antwort als etwas, das fehlen kann:

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

Für die älteren Frameworks überprüfe das Argument, bevor du es indizierst:

lua
QBCore.Functions.TriggerCallback('my_script:getJob', function(job)
    if not job then return end
    print(job)
end)

Welchen du verwenden solltest

  • Schreiben für nur ein Framework: sein eigener Callback ist in Ordnung.
  • Schreiben für mehrere Frameworks, oder für QBox: verwende ox_lib, daher funktioniert ein Callback überall.
  • Schreiben von neuem Code: lib.callback gibt Werte zurück und liest sich wie eine normale Funktion, was Fehler leichter zu finden macht.

Wenn du ein Script zwischen ESX und QBCore portierst, sind die Callback-Namen eine Reihe in der Funktionskarte.

Checkliste

Symptom Behebung
Ergebnis ist nil Überprüfe, dass der Name genau auf beiden Seiten übereinstimmt
Antwortet nie Stelle sicher, dass die Server-Datei im Manifest ist und die Ressource startete
Fehler in der Server-Konsole Behebe es; ein fehlgeschlagener Callback sendet keine Antwort
ESX oder QBCore: keine Antwort auf einigen Pfaden Rufe cb(...) auf jedem Zweig auf
ox_lib: nil Ergebnis Füge return zu der lib.callback.register Funktion hinzu
lib ist nil Füge shared_script '@ox_lib/init.lua' zum Manifest hinzu

Kurze Antworten

Was ist der Unterschied zwischen einem Callback und einem Event?

Ein Event sendet eine Nachricht und wartet nicht auf eine Antwort. Ein Callback fragt die andere Seite und bekommt einen Wert zurück, daher kann der Client Daten verwenden, die nur der Server kennt.

Kann ich ox_lib Callbacks auf ESX oder QBCore verwenden?

Ja. ox_lib ist unabhängig vom Framework, daher funktioniert lib.callback auf ESX, QBCore und QBox, solange ox_lib gestartet und vom Script geladen wird.

Warum stoppt lib.callback.await mein Script für eine Weile?

Es wartet auf die Antwort des Servers, daher ergibt es den Thread. Wenn der Server niemals antwortet, weil der Callback fehlt oder einen Fehler hat, wartet der Thread weiter oder schlägt mit einem Fehler fehl.

Scripts ohne dieses Problem

Advanced BoostingFahrzeug-Boosting per Tablet: Aufträge von Klasse D bis S+, Crews und eine Live-Warteschlange.Script ansehen →Quest CreatorEin visueller Editor für Quests und NPC-Dialoge, Node für Node im Spiel gebaut.Script ansehen →Pawn Shop AppEin Pfandmarkt zwischen Spielern, direkt in lb-phone.Script ansehen →

Weiterlesen