金士顿KTD-INSP6000C/2G内存

博客提及了修订号为9905295 - 091.A00LF ,但未提供更多信息技术相关关键信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

修订号:9905295-091.A00LF
// const request = require('./request.js'); // // 华为云配置(需替换为实际值) // const config = { // iamEndpoint: 'https://iam.cn-south-1.myhuaweicloud.com', // iotEndpoint: 'https://iotda.cn-south-1.myhuaweicloud.com', // credentials: { // username: 'KTD', // password: 'asd456852', // domain: { // name: 'hid_k2jbvvc8omizoea', // id: '1c6efe1c939a4665900226ba17663bbc' // 必须添加 // } // } // }; // // 全局Token缓存 // let tokenCache = { // token: null, // expiresAt: 0 // }; // // 获取IAM Token(官方推荐方式) // async function getIamToken() { // const url = `${config.iamEndpoint}/v3/auth/tokens`; // const authData = { // auth: { // identity: { // methods: ["password"], // password: { // user: { // name: config.credentials.username, // password: config.credentials.password, // domain: { // name: config.credentials.domain.name // } // } // } // }, // scope: { // domain: { // id: config.credentials.domain.id // 关键修改点 // } // } // } // }; // const headers = { // 'Content-Type': 'application/json', // 'X-Domain-Id': config.credentials.domain.id, // 必须添加 // 'X-Language': 'zh-cn' // }; // try { // const response = await request.post(url, authData, headers, true); // return response.header['X-Subject-Token']; // } catch (error) { // console.error('Token获取失败:', { // request: { url, data: authData }, // response: error.response?.data // }); // throw error; // } // } // // 查询设备消息(带自动Token管理) // async function queryDeviceMessages(deviceId) { // const token = await getIamToken(); // const url = `${config.iotEndpoint}/v5/iot/${config.projectId}/devices/${deviceId}/messages`; // return await request.get(url, {}, { // 'Content-Type': 'application/json', // 'X-Auth-Token': token // }); // } // // 下发设备命令 // async function sendDeviceCommand(deviceId, serviceId, command) { // const token = await getIamToken(); // const url = `${config.iotEndpoint}/v5/iot/${config.projectId}/devices/${deviceId}/commands`; // return await request.post(url, { // service_id: serviceId, // command_name: 'control', // paras: { value: command } // }, { // 'Content-Type': 'application/json', // 'X-Auth-Token': token // }); // } // module.exports = { // getIamToken, // queryDeviceMessages, // sendDeviceCommand // }; // // iam-iot.js(或你的小程序里对应的文件名) // const request = require('./request.js'); // 你自己的封装模块 // // —— 一、华为云配置 —— // // 请务必替换以下各项为你项目/账号下的真实值 // const config = { // iamEndpoint: 'https://iam.cn-south-1.myhuaweicloud.com', // iotEndpoint: 'https://iotda.cn-south-1.myhuaweicloud.com', // projectId: '67f73bd1b696b3426f2f3d0a', // ← 新增:在 IoTDA 里创建项目后会拿到 // credentials: { // username: 'KTD', // 你的 IAM 用户名 // password: 'asd456852', // 你的 IAM 用户密码 // domain: { // name: 'hid_k2jbvvc8omizoea', // 你的 IAM 域名称 // id: '1c6efe1c939a4665900226ba17663bbc' // 你的 IAM 域 ID(必填) // } // } // }; // // —— 二、全局 Token 缓存对象 —— // // 用来在有效期内重复使用同一个 IAM Token,减少不必要的网络请求 // let tokenCache = { // token: null, // 当前缓存的 X-Subject-Token // expiresAt: 0 // UNIX 时间戳(毫秒),表示 token 的过期时间 // }; // /** // * 将华为云返回的 ISO8601 时间字符串(如 "2025-06-01T15:28:31.000Z")转换为 JS 的毫秒时间戳 // */ // function parseIsoToTimestamp(isoStr) { // return new Date(isoStr).getTime(); // } // /** // * 获取(或从缓存返回)IAM Token // * - 如果缓存里 token 还没过期,则直接返回它 // * - 否则调用 /v3/auth/tokens 接口重新获取(Domain 级别) // */ // async function getIamToken() { // // 1. 如果缓存里已有 token 且未过期,直接复用 // const now = Date.now(); // if (tokenCache.token && tokenCache.expiresAt > now + 2 * 1000) { // // 提前 2 秒作为缓冲,防止刚好到点就过期的情况 // return tokenCache.token; // } // // 2. 缓存失效或不存在,需要重新请求 // const url = `${config.iamEndpoint}/v3/auth/tokens`; // const authData = { // auth: { // identity: { // methods: ["password"], // password: { // user: { // name: config.credentials.username, // password: config.credentials.password, // domain: { // name: config.credentials.domain.name // } // } // } // }, // scope: { // domain: { // id: config.credentials.domain.id // } // } // } // }; // // 3. 构造必要的请求头(只需 Content-Type、X-Domain-Id、X-Language) // const headers = { // 'Content-Type': 'application/json;charset=UTF-8', // 'X-Domain-Id': config.credentials.domain.id, // 'X-Language': 'zh-cn' // }; // try { // // 注意:request.post 方法的最后一个参数若为 true,表明需要拿到完整 response(含 header & body) // const response = await request.post(url, authData, headers, true); // // 4. 从响应头中取到 Token // const newToken = response.header['X-Subject-Token']; // if (!newToken) { // throw new Error("IAM 返回未携带 X-Subject-Token"); // } // // 5. 从响应体里读取 token.expires_at 字段,计算过期时间戳 // // 假设 response.data.token.expires_at 是类似 "2025-06-01T15:28:31.000Z" 的字符串 // const respBody = response.data; // const expiresAtIso = respBody.token && respBody.token.expires_at; // if (!expiresAtIso) { // // 如果后端没有返回 expires_at,也可以直接缓存 1 小时后再刷新 // console.warn("未从 IAM 响应体里读取到 expires_at,默认缓存 3600 秒"); // tokenCache.expiresAt = now + 3600 * 1000; // } else { // tokenCache.expiresAt = parseIsoToTimestamp(expiresAtIso); // } // // 6. 更新全局缓存并返回 // tokenCache.token = newToken; // return newToken; // } catch (err) { // console.error('IAM Token 获取失败:', { // request: { url, data: authData, headers }, // error: err.response?.data || err.message // }); // throw err; // } // } // /** // * 查询设备消息(自带自动 Token 管理) // * @param {string} deviceId 设备 ID // */ // async function queryDeviceMessages(deviceId) { // const token = await getIamToken(); // const url = `${config.iotEndpoint}/v5/iot/${config.projectId}/devices/${deviceId}/messages`; // const headers = { // 'Content-Type': 'application/json;charset=UTF-8', // 'X-Auth-Token': token // }; // try { // return await request.get(url, {}, headers); // } catch (err) { // console.error('查询设备消息失败:', { // url, // deviceId, // error: err.response?.data || err.message // }); // throw err; // } // } // /** // * 下发设备命令(自带自动 Token 管理) // * @param {string} deviceId 设备 ID // * @param {string} serviceId 服务 ID(对应在 IoTDA 控制台定义的能力服务 ID) // * @param {any} command 下发给设备的参数内容,比如 { value: true } 或其他 JSON 对象 // */ // async function sendDeviceCommand(deviceId, serviceId, command) { // const token = await getIamToken(); // const url = `${config.iotEndpoint}/v5/iot/${config.projectId}/devices/${deviceId}/commands`; // const body = { // service_id: serviceId, // command_name: 'control', // 如果你在控制台定义的命令名不是固定 "control",请替换为实际命令名称 // paras: command // 直接把用户传进来的 command 对象放在 paras 下 // }; // const headers = { // 'Content-Type': 'application/json;charset=UTF-8', // 'X-Auth-Token': token // }; // try { // return await request.post(url, body, headers); // } catch (err) { // console.error('下发设备命令失败:', { // url, // deviceId, // serviceId, // command, // error: err.response?.data || err.message // }); // throw err; // } // } // module.exports = { // getIamToken, // queryDeviceMessages, // sendDeviceCommand // }; const request = require('./request.js'); // 华为云配置(需替换为实际值) const config = { iamEndpoint: 'https://iam.cn-south-1.myhuaweicloud.com', iotEndpoint: 'https://iotda.cn-south-1.myhuaweicloud.com', projectId: '8dc9c3dfebf14076adb6b8420fbb09a0', credentials: { username: 'KTD', password: 'asd456852', domain: { name: 'hid_k2jbvvc8omizoea', id: '1c6efe1c939a4665900226ba17663bbc' } }, // 新增:网络请求配置 network: { timeout: 10000, // 请求超时时间(毫秒) maxRetries: 3 // 最大重试次数 } }; // 全局Token缓存 let tokenCache = { token: null, expiresAt: 0 }; /** * 将华为云返回的ISO8601时间字符串转换为JS时间戳 */ function parseIsoToTimestamp(isoStr) { return new Date(isoStr).getTime(); } /** * 获取(或从缓存返回)IAM Token */ async function getIamToken() { const now = Date.now(); // 提前2分钟刷新token,避免临界点问题 if (tokenCache.token && tokenCache.expiresAt > now + 2 * 60 * 1000) { return tokenCache.token; } const url = `${config.iamEndpoint}/v3/auth/tokens`; const authData = { auth: { identity: { methods: ["password"], password: { user: { name: config.credentials.username, password: config.credentials.password, domain: { name: config.credentials.domain.name } } } }, scope: { domain: { id: config.credentials.domain.id } } } }; const headers = { 'Content-Type': 'application/json;charset=UTF-8', 'X-Domain-Id': config.credentials.domain.id, 'X-Language': 'zh-cn' }; try { const response = await request.post(url, authData, headers, true, { timeout: config.network.timeout }); const newToken = response.header['X-Subject-Token']; if (!newToken) { throw new Error("未从响应头中获取到X-Subject-Token"); } const expiresAtIso = response.data?.token?.expires_at; if (expiresAtIso) { tokenCache.expiresAt = parseIsoToTimestamp(expiresAtIso); } else { console.warn("未获取到token过期时间,默认缓存1小时"); tokenCache.expiresAt = now + 3600 * 1000; } tokenCache.token = newToken; console.log(`获取新Token成功,有效期至: ${new Date(tokenCache.expiresAt).toLocaleString()}`); return newToken; } catch (error) { console.error('获取IAM Token失败:', error.message); // 清空无效的token tokenCache = { token: null, expiresAt: 0 }; throw error; } } /** * 带重试机制的HTTP请求 */ async function requestWithRetry(requestFn, retries = config.network.maxRetries) { let lastError; for (let i = 0; i < retries; i++) { try { return await requestFn(); } catch (error) { lastError = error; console.warn(`请求失败,尝试第${i+1}/${retries}次重试:`, error.message); // 指数退避策略 await new Promise(resolve => setTimeout(resolve, 500 * (i + 1))); } } console.error(`达到最大重试次数(${retries}),请求最终失败`); throw lastError; } /** * 查询设备消息 */ async function queryDeviceMessages(deviceId) { const token = await getIamToken(); // 对设备ID进行编码,防止URL格式错误 const encodedDeviceId = encodeURIComponent(deviceId); const url = `${config.iotEndpoint}/v5/iot/${config.projectId}/devices/${encodedDeviceId}/messages`; return requestWithRetry(async () => { return await request.get(url, {}, { 'Content-Type': 'application/json;charset=UTF-8', 'X-Auth-Token': token }, { timeout: config.network.timeout }); }); } /** * 下发设备命令 */ async function sendDeviceCommand(deviceId, serviceId, commandName, paras) { const token = await getIamToken(); const encodedDeviceId = encodeURIComponent(deviceId); const url = `${config.iotEndpoint}/v5/iot/${config.projectId}/devices/${encodedDeviceId}/commands`; return requestWithRetry(async () => { return await request.post(url, { service_id: serviceId, // 使用传入的服务ID command_name: commandName, // 使用动态命令名称 paras: paras // 参数必须为对象格式 }, { 'Content-Type': 'application/json;charset=UTF-8', 'X-Auth-Token': token }, { timeout: config.network.timeout }); }); } module.exports = { getIamToken, queryDeviceMessages, sendDeviceCommand }; 这里面的token是全局的吗还是在单个文件中的
最新发布
06-03
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值