node.js - 在 Node.js 中打开多个 UNIX 域套接字 : Why do I get EAGAIN errors?

标签 node.js sockets unix-socket

我的用例(网络服务):

多个客户端 => Web 服务器 => 通过 UNIX 域套接字向 C 程序发送消息。

我一直在使用 Apache + PHP 作为 Web 服务器层,但目前正在将其替换为 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 应用程序是否有好处,但我想我还是提到了它。

关于node.js - 在 Node.js 中打开多个 UNIX 域套接字 : Why do I get EAGAIN errors?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32993000/

相关文章:

node.js - 为 Moodle 创建 LTI 提供程序

node.js - 如何从 Google Cloud Functions (nodeJS) 发送 HTTP 请求

c - Linux 在使用 PPID 1 重新启动时不会清理资源(套接字)

linux - 从多个线程对同一个 TCP 套接字发出阻塞 write() 调用是否安全?

c++ - boost ASIO 和线程之间的消息传递

c - sendmsg/recvmsg 中的部分读/写问题

node.js - 清空请求正文

node.js - websocket服务器expressjs中的动态路由

linux - ZeroMQ:检查是否有人在 Unix 域套接字后面监听

docker - 如何使用 Netty 连接到运行 HTTP 服务器的 UNIX 域套接字?