FiveM FXServer服务端触发客户端事件失败,寻求服务端向JavaScript传递数据的解决方案
FiveM FXServer服务端触发客户端事件失败,寻求服务端向JavaScript传递数据的解决方案
老哥我帮你排查了下代码,核心问题出在服务端触发客户端事件的参数错误,还有你在JS里直接操作MySQL的误区,给你一步步理清楚:
一、先解决事件触发失败的核心问题
你服务端代码里的TriggerClientEvent用错参数了!FiveM里TriggerClientEvent的第二个参数需要传玩家的服务器端ID(也就是source,是个数字),而不是你传的identifier(license字符串)。FiveM根本识别不了用license当目标的客户端事件,这就是事件一直不触发的原因!
修正后的服务端代码:
RegisterNetEvent('ch_nui:kok') AddEventHandler('ch_nui:kok',function () print('2') local playerSource = source -- 这是触发事件的玩家的服务器ID,是数字类型 local identifier = GetPlayerIdentifierByType(playerSource,'license') -- 把第二个参数改成source,才能精准触发对应玩家的客户端事件 TriggerClientEvent('ch_nui:bob', playerSource, identifier) end)
顺带修正客户端的小问题
你的客户端代码里print('1')少了闭合括号,虽然不是事件不触发的原因,但会导致代码报错,顺便补全:
RegisterNetEvent('ch_nui:bob') AddEventHandler('ch_nui:bob',function (identifier) print('1') -- 补全闭合括号 CreateThread(function () print('1') -- 补全闭合括号 while true do Wait(50) local playerId = PlayerPedId() local playerCoords = GetEntityCoords(playerId) local playerHeading = GetEntityHeading(playerId) SendNUIMessage({ type = 'position', x = playerCoords.x, y = playerCoords.y, z = playerCoords.z, heading = playerHeading, }) -- 注意这里type要和JS里判断的`identifier`对应,你之前写的是`identifierr`,JS里判断的是`type === 'identifier'`,要统一! SendNUIMessage({ type='identifier', identifierr = identifier }) end end) end) TriggerServerEvent('ch_nui:kok')
二、你踩了一个大误区:JS不能直接操作MySQL!
你的JS代码里直接用MySQL.scalar是完全无效的!NUI的JavaScript运行在客户端的浏览器进程里,根本没有权限(也没有对应的模块)直接连接数据库,所有数据库操作必须在服务端执行,然后把结果传递给客户端,再转发给JS。
三、服务端到JavaScript传递数据的更优方案
除了“服务端→客户端事件→SendNUIMessage到JS”的方式,更推荐用NUI回调,不用一直循环发送消息,按需请求数据更高效:
方案示例:用NUI回调获取玩家余额
- 客户端注册NUI回调(接收JS的请求,向服务端要数据)
-- 客户端代码 RegisterNUICallback('getPlayerMoney', function(data, cb) -- 向服务端发起回调请求 TriggerServerCallback('ch_nui:getPlayerMoney', function(playerMoney) -- 把服务端返回的余额传给JS cb(playerMoney) end) end)
- 服务端注册回调(执行数据库查询,返回结果)
-- 服务端代码 RegisterServerCallback('ch_nui:getPlayerMoney', function(source, cb) local identifier = GetPlayerIdentifierByType(source, 'license') -- 服务端执行数据库查询 local money = MySQL.scalar('SELECT `money` FROM `money` WHERE `identifier` = ? LIMIT 1', {identifier}) -- 把查询结果返回给客户端 cb(money or 0) -- 加个默认值防止空值 end)
- JS里调用NUI回调(按需请求数据)
// JS代码 // 当需要获取余额时调用 async function getPlayerMoney() { try { const resp = await fetch('https://你的资源名/getPlayerMoney', { method: 'POST', headers: { 'Content-Type': 'application/json; charset=UTF-8', }, body: JSON.stringify({}) }); const money = await resp.json(); console.log('玩家余额:', money); return money; } catch (err) { console.error('获取余额失败:', err); return 0; } } // 调用示例 getPlayerMoney();
这样就能安全、高效地把服务端数据库里的数据传递到JS里了。
备注:内容来源于stack exchange,提问作者DiSpiderPig
相关产品推荐
相关产品推荐

