Node.js使用node-xmlrpc与XML-RPC服务器通信、图片base64编码及批量调用问题
关于node-xmlrpc使用的两个问题解决方案
问题1:从URL下载图片转码后发送到XML-RPC服务器
node-xmlrpc会自动识别Buffer类型参数,将其序列化为XML-RPC规范中的base64数据类型,无需手动处理XML标签格式,实现逻辑如下:
- 先请求图片URL获取原始二进制Buffer
- 可按需转成base64字符串做业务处理,再转回二进制Buffer传入调用参数即可,不需要中间处理的话也可直接传原始Buffer
示例代码:
const https = require('https') const xmlrpc = require('xmlrpc') // 初始化XML-RPC客户端 const client = xmlrpc.createClient({ host: '你的XML-RPC服务域名/IP', port: 80, path: '/xmlrpc接口路径' }) // 下载图片并转成符合要求的Buffer function getProcessedImageBuffer(imageUrl) { return new Promise((resolve, reject) => { https.get(imageUrl, (res) => { const chunks = [] res.on('data', chunk => chunks.push(chunk)) res.on('end', () => { const rawBuffer = Buffer.concat(chunks) // 转base64字符串,若无需使用base64做其他业务处理可跳过下面两行 const base64Str = rawBuffer.toString('base64') const processedBuffer = Buffer.from(base64Str, 'base64') // 直接返回rawBuffer效果完全一致 resolve(processedBuffer) }) res.on('error', reject) }) }) } // 单调用上传示例 getProcessedImageBuffer('https://example.com/test.jpg').then(imageBuffer => { client.methodCall('你的上传图片方法名', [imageBuffer, '其他业务参数'], (error, res) => { if (error) { console.error('调用失败:', error) return } console.log('调用成功返回:', res) }) }).catch(err => console.error('图片下载失败:', err))
问题2:node-xmlrpc批量调用请求
有两种实现方案,可根据服务器支持情况选择:
方案1:标准XML-RPC批量调用(推荐)
兼容支持system.multicall标准批量方法的XML-RPC服务器,仅发起一次HTTP请求,性能更高:
// 组装批量调用参数,顺序和返回结果顺序一一对应 const multiTasks = [ { methodName: '方法1名称', params: ['参数1', '参数2'] }, { methodName: '方法2名称', params: [123, '其他参数'] }, { methodName: '上传图片方法名', params: [imageBuffer] // 可直接传入前面处理好的图片Buffer } ] // 发起批量调用 client.methodCall('system.multicall', [multiTasks], (error, results) => { if (error) { console.error('批量调用失败:', error) return } // results为数组,顺序和传入的multiTasks顺序一致 console.log('批量调用返回结果:', results) })
方案2:并行独立调用
如果服务器不支持system.multicall方法,可以自行并行发起多个独立调用:
// 把每个调用封装成Promise const task1 = new Promise((resolve, reject) => { client.methodCall('方法1名称', ['参数'], (err, res) => err ? reject(err) : resolve(res)) }) const task2 = new Promise((resolve, reject) => { client.methodCall('方法2名称', ['参数'], (err, res) => err ? reject(err) : resolve(res)) }) Promise.all([task1, task2]).then(results => { // results顺序和task1、task2的顺序一致 console.log('所有调用完成:', results) }).catch(err => { console.error('某一个调用失败:', err) })
内容的提问来源于stack exchange,提问作者Jiři Hruška
相关产品推荐
相关产品推荐

