La callback del server ritorna nil: ESX, QBCore e callback ox_lib
ESX.TriggerServerCallback, QBCore TriggerCallback e lib.callback.await ritorna nil? Come ogni callback funziona sul server e client, e le ragioni per cui ritornano nulla.
Uno script client chiede al server dati, e quello che torna è nil, o nulla affatto:
SCRIPT ERROR: @my_script/client/main.lua:21: attempt to index a nil value (local 'result')Le callback del server sono come il client chiede al server una domanda e ottiene una risposta. Ogni framework ha la sua, e ox_lib ha una che funziona ovunque. Questo articolo mostra i tre e perché ritornano nil.
ESX
Registra sul server, attiva dal 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)La funzione del server ottiene source e cb, e passi la risposta a cb. Gli argomenti extra dal client arrivano dopo cb. La funzione client riceve quello che cb ha inviato.
QBCore
I nomi differiscono, la forma è la stessa:
-- 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)Se ESX o QBCore è nil dentro lo script, la callback non si registra mai. Vedi ESX è nil e QBCore è nil.
ox_lib
Le callback ox_lib non hanno bisogno di un framework, e la risposta è un valore di ritorno invece di una funzione cb:
-- 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)Il secondo argomento di await è un ritardo in millisecondi tra la chiamata e la risposta (usa false per nessuno). Gli argomenti per il server lo seguono:
local ok = lib.callback.await('my_script:buy', false, 'burger', 2)lib.callback.register('my_script:buy', function(source, item, amount)
-- ...
return true
end)Affinché la callback esista, lo script carica ox_lib nel suo manifest:
shared_script '@ox_lib/init.lua'Senza di esso, lib è nil: vedi ox_lib init.lua non trovato.
Il server può anche chiamare un client: lib.callback.await('name', playerId, ...) sul server, con lib.callback.register sul client. Se preferisci non aspettare, lib.callback('name', false, function(result) end) prende una funzione invece.
Perché una callback ritorna nil
Quasi ogni caso è uno di questi:
- Il nome non corrisponde. Il registro e i nomi di attivazione devono essere identici, incluso caso. Un typo non solleva un errore che noterai, non risponde solo mai.
- Non è registrato. Il file del server non è mai corso: manca da
server_scripts, la risorsa non si è avviata, o è fallita prima di raggiungere la riga di registrazione. - Un errore sul server, prima della risposta. Se la funzione del server dà errore, per esempio
xPlayerè nil, la risposta non è mai inviata. Controlla la console del server, non quella del client. - Non chiami
cbsu ogni percorso. Su ESX e QBCore, un branch che ritorna senza chiamarecb(...)lascia il client ad aspettare:
-- 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)- Hai dimenticato
returnsu ox_lib. Una funzionelib.callback.registerche non hareturnrispondenil. - Chiami troppo presto. Una callback client attivata all'avvio dello script può raggiungere il server prima che il suo registro sia corso, dopo un riavvio per esempio. Attivala dopo che il giocatore è caricato.
- Stili misti. Una callback registrata con
lib.callback.registernon può essere chiamata conESX.TriggerServerCallback. Usa la coppia corrispondente.
Suggerimento: per scoprire quale caso hai, aggiungi un
Proteggi da nil sul client
Tratta la risposta come qualcosa che può mancare:
local money = lib.callback.await('my_script:getMoney', false)
if not money then
return print('No answer from the server')
endPer i framework più vecchi, controlla l'argomento prima di indicizzarlo:
QBCore.Functions.TriggerCallback('my_script:getJob', function(job)
if not job then return end
print(job)
end)Quale usare
- Scrivere solo per un framework: la sua callback è fine.
- Scrivere per molti framework, o per QBox: usa ox_lib, così una callback funziona ovunque.
- Scrivere codice nuovo:
lib.callbackritorna valori e legge come una funzione normale, il che rende i errori più facili da individuare.
Se porti uno script tra ESX e QBCore, i nomi delle callback sono una riga nella mappa funzionale.
Checklist
| Sintomo | Soluzione |
|---|---|
| Il risultato è nil | Controlla che il nome corrisponda esattamente su entrambi i lati |
| Non risponde mai | Assicurati che il file del server sia nel manifest e la risorsa sia avviata |
| Errore nella console del server | Correggilo; una callback fallita non invia risposta |
| ESX o QBCore: nessuna risposta su alcuni percorsi | Chiama cb(...) su ogni branch |
| ox_lib: risultato nil | Aggiungi return alla funzione lib.callback.register |
lib è nil |
Aggiungi shared_script '@ox_lib/init.lua' al manifest |
Risposte rapide
Qual è la differenza tra una callback e un evento?
Un evento invia un messaggio e non aspetta una risposta. Una callback chiede all'altro lato e ottiene un valore indietro, così il client può usare dati che solo il server sa.
Posso usare le callback ox_lib su ESX o QBCore?
Sì. ox_lib è indipendente dal framework, quindi lib.callback funziona su ESX, QBCore e QBox finché ox_lib è avviato e caricato dallo script.
Perché lib.callback.await ferma il mio script per un po'?
Aspetta la risposta del server, quindi cede il thread. Se il server non risponde mai perché la callback è mancante o dà errore, il thread continua ad aspettare o fallisce con un errore.
Script senza questo problema
Advanced BoostingBoosting di veicoli dal tablet: contratti dalla classe D alla S+, crew e coda in tempo reale.Vedi script →
Quest CreatorUn editor visuale di missioni e dialoghi con gli NPC, costruito nodo per nodo in gioco.Vedi script →
Pawn Shop AppUn banco dei pegni tra giocatori dentro lb-phone.Vedi script →