Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/37.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Node.js中打开多个UNIX域套接字:为什么会出现EAGAIN错误?_Node.js_Sockets_Unix Socket - Fatal编程技术网

在Node.js中打开多个UNIX域套接字:为什么会出现EAGAIN错误?

在Node.js中打开多个UNIX域套接字:为什么会出现EAGAIN错误?,node.js,sockets,unix-socket,Node.js,Sockets,Unix Socket,我的用例(webservice): 多个客户端=>Webserver=>通过UNIX域套接字发送给C程序的消息 我一直在为Web服务器层使用Apache+PHP,但目前我正在用Node.js替换它 Web服务每秒最多可收到100个请求,因此,当新请求出现时,C程序会很忙,这是一个非常真实的场景。PHP很好地处理了这一点,但Node.js经常会失败,并出现以下错误: { "code": "EAGAIN", "errno": "EAGAIN", "syscall": "connect",

我的用例(webservice):

多个客户端=>Webserver=>通过UNIX域套接字发送给C程序的消息

我一直在为Web服务器层使用Apache+PHP,但目前我正在用Node.js替换它

Web服务每秒最多可收到100个请求,因此,当新请求出现时,C程序会很忙,这是一个非常真实的场景。PHP很好地处理了这一点,但Node.js经常会失败,并出现以下错误:

{
  "code": "EAGAIN",
  "errno": "EAGAIN",
  "syscall": "connect",
  "address": "/tmp/service.sock"
}
我假设这是因为PHP执行某种消息队列/重试,以确保所有消息都发送到C程序(Node.js没有)

在Node.js中是否有一种简单的方法来执行相同的操作,或者我必须实现一个自定义消息队列?

C套接字创建:

int listenSocket, newSocket;
struct sockaddr_un localAddress, remoteAddress;

// Create socket
if ((listenSocket = socket(AF_UNIX, SOCK_STREAM, 0)) == -1){
  printf("Error opening listener socket");
  exit(1);
}

// Configure socket
localAddress.sun_family = AF_UNIX; // Set UNIX domain socket type
strcpy(localAddress.sun_path, "/tmp/service.sock");
unlink(localAddress.sun_path); // Remove any previous instances of the socket

// Open listener socket
int len = strlen(localAddress.sun_path) + sizeof(localAddress.sun_family);
if (bind(listenSocket, (struct sockaddr *)&localAddress, len) == -1){
  printf("Error binding socket at %s", localAddress.sun_path);
  exit(1);
}
chmod(localAddress.sun_path, 0777);

// Listen for new connections on the listener socket
if (listen(listenSocket, 5) == -1){
  printf("Error listening on listener socket");
  exit(1);
}

// Handle new connections
while(!shutdown){
  printf("Waiting for a connection...\n");

  // Accept new connection
  int sizeofRemoteAddress = sizeof(remoteAddress);
  if ((newSocket = accept(listenSocket, (struct sockaddr *)&remoteAddress, &sizeofRemoteAddress)) == -1){
    printf("Error accepting new connection: %s\n", strerror(errno));
    continue;
  }

  // Read and handle data from client...
}
连接到PHP中的套接字:

$socket = @socket_create(AF_UNIX, SOCK_STREAM, 0);
if (!$socket) return false;

$connected = @socket_connect($socket, "/tmp/service.sock");
if (!$connected) return false;

// Send message to server and read response...
连接到Node.js中的套接字:

new Promise(function(resolve, reject){
  var socket = Net.connect("/tmp/service.sock");

  socket.on("error", function(err){
    reject(err);
  });

  socket.on("connect", function(){
    socket.write(message);
  });

  socket.on("data", function(data){
    socket.end();
    resolve(data.toString("UTF-8"));
  });
});

EAGAIN
是系统调用中断时的预期情况。您只需在得到
EAGAIN
错误代码时重复相同的调用即可。在典型的C程序中,您将看到大量的
while(returnCode==-1&&errno==EAGAIN)
类型的循环。 如果预计会有很多中断,可以先禁用中断(不确定在node.js中是如何实现的)执行系统调用,然后再次启用中断。
我不确定这个答案是否适合
node.js
应用程序,但我想我还是提到了它。

我将您的答案解释为“不,实现一个消息队列”。您的解释很有道理,因为我看到
ksoftirqd
进程(中断处理程序)中的CPU负载很重,我在PHP源代码中发现了一些与您的示例类似的代码。在此期间,我确实完成了消息队列的制作——这是一个可能产生更好性能的解决方案,并且比
while(EAGAIN)
循环“更好”