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:
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:
-- 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)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:
-- 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)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:
-- 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)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:
local ok = lib.callback.await('my_script:buy', false, 'burger', 2)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:
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:
- 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.
- 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. - Ein Fehler auf dem Server, vor der Antwort. Wenn die Server-Funktion einen Fehler hat, zum Beispiel
xPlayerist nil, wird die Antwort nie gesendet. Überprüfe die Server-Konsole, nicht die Client-Konsole. - Du rufst
cbnie auf jedem Pfad auf. Auf ESX und QBCore hinterlässt ein Zweig, der ohnecb(...)aufzurufen zurückgegeben wird, den Client, der wartet:
-- 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)- Du hast
returnbei ox_lib vergessen. Einelib.callback.registerFunktion, die keinreturnhat, antwortet mitnil. - 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.
- Gemischte Stile. Ein Callback, der mit
lib.callback.registerregistriert ist, kann nicht mitESX.TriggerServerCallbackaufgerufen werden. Verwende das passende Paar.
Tipp: Um herauszufinden, welchen Fall du hast, füge ein
Schütze dich gegen nil auf dem Client
Behandle die Antwort als etwas, das fehlen kann:
local money = lib.callback.await('my_script:getMoney', false)
if not money then
return print('No answer from the server')
endFür die älteren Frameworks überprüfe das Argument, bevor du es indizierst:
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.callbackgibt 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 →