Nodejs 使用cluster模块时,master和worker之间发送消息中文乱码问题

Nodejs 使用cluster模块时,master和worker之间发送消息中文乱码问题

var cluster, masterStart, workerStart, fs;

cluster = require(“cluster”); fs = require(‘fs’);

masterStart = function() { var worker; worker = cluster.fork(); worker.on(“message”, function(msg) { console.log("get msg: " + msg.length); process.exit(); }); };

workerStart = function() { var a; a = require("./a.json"); setTimeout(function() { console.log("start send: " + JSON.stringify(a).length); process.send(JSON.stringify(a)); }, 20000); };

if (cluster.isMaster) { masterStart(); } else { workerStart(); }

a.json 是一个大json文件,总大小大概4M,里面有挺多中文字符。
传递过去后,发现传递前和传递后的字符串长度不一致,传递前 4195514, 传递后变成了 4195536。
对比后发现,部分中文字符乱码了。使用ultraedit查看乱码部分的十六进制编码为“EF BF BD EF BF BD EF BF BD”。
猜测是中文被截断了,导致解析不了,所以成了未知字符。不知道大家有没有遇到过这种问题。
目前的解决方式是用base64编码一下后再传递,接收到后再解码,就没有问题了。
不知道除此之外有没有什么好的解决办法呢?或者如何能避免这样的问题呢?


3 回复

Node.js 使用 cluster 模块时,master 和 worker 之间发送消息中文乱码问题

在使用 Node.js 的 cluster 模块时,有时会遇到 master 和 worker 之间发送消息时出现中文乱码的问题。本文将通过一个具体的例子来说明这个问题,并提供一种解决方案。

示例代码

var cluster, masterStart, workerStart, fs;

cluster = require("cluster");
fs = require('fs');

// Master 进程
masterStart = function() {
  var worker;
  worker = cluster.fork();
  worker.on("message", function(msg) {
    console.log("收到消息: " + msg);
    process.exit();
  });
};

// Worker 进程
workerStart = function() {
  var a;
  a = require("./a.json");
  setTimeout(function() {
    console.log("开始发送: " + Buffer.byteLength(JSON.stringify(a), 'utf8'));
    process.send(JSON.stringify(a));
  }, 20000);
};

if (cluster.isMaster) {
  masterStart();
} else {
  workerStart();
}

问题描述

在这个例子中,a.json 文件是一个包含大量中文字符的大 JSON 文件,大约有 4MB 大小。当尝试从 worker 进程向 master 进程发送 JSON 数据时,发现中文字符出现了乱码。具体表现为:

  • 发送前的字符串长度为 4195514。
  • 接收后的字符串长度变为 4195536。
  • 部分中文字符乱码,十六进制编码显示为 “EF BF BD EF BF BD EF BF BD”。

这表明在传输过程中某些字符被损坏或截断,导致解析失败。

解决方案

一种常见的解决方法是使用 Base64 编码对数据进行编码和解码。具体步骤如下:

  1. 在 worker 进程中,将 JSON 数据转换为 Base64 字符串。
  2. 在 master 进程中,接收 Base64 字符串并将其解码回原始 JSON 数据。

示例代码(Base64 编码)

// workerStart 函数修改
workerStart = function() {
  var a;
  a = require("./a.json");
  setTimeout(function() {
    console.log("开始发送: " + Buffer.byteLength(JSON.stringify(a), 'utf8'));
    // 使用 Base64 编码
    process.send(Buffer.from(JSON.stringify(a)).toString('base64'));
  }, 20000);
};

// masterStart 函数修改
masterStart = function() {
  var worker;
  worker = cluster.fork();
  worker.on("message", function(msg) {
    // 使用 Base64 解码
    console.log("收到消息: " + Buffer.from(msg, 'base64').toString());
    process.exit();
  });
};

结论

通过使用 Base64 编码和解码,可以有效避免中文乱码问题。这种方法确保了数据在传输过程中的完整性,避免了字符截断或损坏的情况。希望这个解决方案对你有所帮助!


改参数试试吧

{encoding: ‘binary’}

在使用 Node.js 的 cluster 模块时,masterworker 之间发送消息可能会遇到中文乱码问题。这通常是因为在传输过程中没有正确处理字符编码。一种常见的解决方法是使用 Base64 编码来确保数据在传输过程中的完整性。

示例代码

以下是改进后的代码示例,展示了如何使用 Base64 编码来解决中文乱码问题:

var cluster = require("cluster");
var fs = require('fs');
var util = require('util');

// 读取 JSON 文件
var a = JSON.parse(fs.readFileSync('./a.json', 'utf8'));

if (cluster.isMaster) {
  // 主进程
  var worker = cluster.fork();
  
  worker.on("message", function(msg) {
    console.log("Received message: ", msg);
    process.exit();
  });
} else {
  // 工作进程
  setTimeout(function() {
    console.log("Sending message: ", Buffer.from(JSON.stringify(a)).toString('base64'));
    process.send(Buffer.from(JSON.stringify(a)).toString('base64'));
  }, 20000);
}

解释

  1. 读取 JSON 文件:使用 fs.readFileSync 读取 JSON 文件,并将其解析为 JavaScript 对象。
  2. 主进程:创建一个工作进程,并监听其消息事件。接收的消息需要先解码 Base64 编码。
  3. 工作进程:在 20 秒后将 JSON 对象转换为字符串,然后使用 Buffer.fromtoString('base64') 将其编码为 Base64 字符串,并通过 process.send 发送。

处理接收的消息

在主进程中,接收到的消息需要进行 Base64 解码:

worker.on("message", function(msg) {
  console.log("Received message: ", Buffer.from(msg, 'base64').toString());
  process.exit();
});

这样可以确保在传输过程中不会出现乱码问题。

回到顶部