socket.io连接到unix socket

时间:2015-02-03 19:03:42

标签: javascript node.js socket.io

我想使用socket.io-client连接到unix socket, 没有成功(主要是超时,最后一个样本 - dns解析错误)。

var clientio  = require('socket.io-client');
// i tried all variants here
//client=clientio.connect('port.io/',{'force new connection': true});
//client=clientio.connect('unix://port.io/',{'force new connection': true});
//client=clientio.connect('http//unix:port.io/',{'force new connection': true});

client.on('connect',connect);

有没有办法将socket.io客户端连接到unix socket?

我使用nc -U port.io检查了服务器套接字,它运行正常。

4 个答案:

答案 0 :(得分:2)

在寻找类似问题的答案时找到了这个。

AFAIK socket.io-client取决于engne.io-clientws取决于var isUnixSocket = serverUrl.protocol === 'ws+unix:';,其中包含以下内容:

var client=clientio.connect('ws+unix:/port.io',{'force new connection': true});

见这里:https://github.com/websockets/ws/blob/4f99812b1095979afaad58865846b160334f3415/lib/WebSocket.js#L598

所以看起来可以通过UNIX套接字连接客户端,只要它在node.js(或类似的东西)中完成 - 我认为不可能在Web浏览器中进行。< / p>

我没有尝试过,但也许这样的事情会起作用:

ws

更新:看起来socket.io和engine.io真的不喜欢UNIX域套接字:(。要通过UDS连接,直接使用Set-Content模块似乎是唯一的方法,但它不会知道socket.io建立在顶部的所有额外的东西(如房间和名称空间)。

答案 1 :(得分:1)

socket.iowebSocket协议之上运行特定协议,然后在普通TCP套接字上运行。如果您尝试连接到普通的Unix套接字,则无法使用socket.io

您可以使用此处描述的net.Sockethttp://nodejs.org/api/net.html根据该文档“是TCP或UNIX套接字的抽象”。

socket.io连接具有非常特定的启动协议,它使用非常具体的有线数据格式和非常特定的消息序列以及热保持保持策略。两端必须支持所有这一切才能使socket.io连接起作用。

普通套接字是最低级别的根传输,但所有其他东西必须存在于该普通套接字之上,以便双方能够使用socket.io相互通信。如果您想要简要概述编写webSocket服务器所涉及的内容,请参阅this article。然后,Socket.io是webSocket传输之上的另一个协议。


这里仍然很困惑。我不知道你为什么提到标准的Unix套接字。

如果您尝试使用socket.io从一个nodejs服务器连接到另一个nodejs服务器,并且其中一个服务器正在运行您在注释中显示的默认socket.io服务器,那么您应该能够执行此操作从另一个连接到socket.io服务器:

var socket = require('socket.io-client')('http://port.io');
socket.on('connect', function(){});
socket.on('event', function(data){});
socket.on('disconnect', function(){});

这假设port.io是您的socket.io服务器的域(可以通过DNS解析指向实际服务器的东西)。您使用的内容必须是实际的HTTP URL,这一点很重要,因为所有webSocket和socket.io连接都是通过对实际HTTP URL的HTTP请求启动的。

我不遵循您尝试使用Unix URL方案做的事情。

答案 2 :(得分:0)

你的问题很模糊,但是因为我来到这里寻找类似的答案,这是我提出的代码。

此代码打开一个unix域套接字,并将收到的所有内容广播到任何连接的socket.io客户端(通过WebSockets)

// Generated by CoffeeScript 1.9.2
var app, domain_server, fs, io, net, server;
fs = require('fs');
net = require('net');
app = require('express')();
server = require('http').Server(app);
io = require('socket.io')(server);

/* Handle Unix Domain Socket
 * * Delete file if it already exists, 
 *   avoiding EADDRINUSE  */

if (fs.existsSync('/tmp/domain_socket')) {
  fs.unlinkSync('/tmp/domain_socket');
}

domain_server = net.createServer(function(socket) {
  socket.on('data', function(data) {
    /* broadcast messages from unix socket to websockets */
    io.sockets.emit('domain-message', data.toString());
  });
});

domain_server.listen('/tmp/domain_socket', function() {
  console.log('domain_server bound');
});


/*
 * Handle Web Serving/WebSockets
 */

server.listen(8080);

app.get('/', function(req, res) {
  res.sendFile(__dirname + '/index.html');
});

io.on('connection', function(socket) {
  socket.emit('message', {
    hello: 'connected'
  });
});

答案 3 :(得分:0)

确定我们能做到。

客户端(在节点8.11中,而不是在浏览器中):

var pipe_name = '/tmp/your-pipe-name';
var channel_name = '/your-namespace';
var server_url = "ws+unix://" + pipe_name + channel_name;

var path = require('path');
var url = require('url');
var WebSocket = require('ws');
var mock = require('mock-require');

class WebSockeMock extends WebSocket {
  constructor (address, protocols, options) {
    var uri = url.parse(server_url);
    var param = url.parse(address).search;
    address = "ws+unix:///" + uri.host + path.dirname(uri.pathname)
      + ":/socket.io/" + param;
    console.log("real ws", address)
    super(address, protocols, options);
  }
}

console.log("connecting to " + server_url);

if (/unix:\/+/.test(server_url)) {
  server_url = server_url.replace(/^[^:]+[:\/\\]+/, 'ws://');
  console.log("fake ws", server_url);
  mock('ws', WebSockeMock);
  process.env.DEBUG = '*';
}

var socket = require('socket.io-client')(server_url, {
  transports: ['websocket']
});

socket.on('connect', function() {
  return console.log("pipe connected");
});

服务器端:

var pipe_name = '/tmp/your-pipe-name';
var channel_name = '/your-namespace';

var fs = require('fs');
var path = require('path');

if (fs.existsSync(pipe_name)) {
  fs.unlinkSync(pipe_name);
}
console.log("pipe server at " + pipe_name);
var io = require('socket.io')(require('http').createServer().listen(pipe_name));
var channel = io.of("/" + (path.basename(pipe_name)) + channel_name)
.on('connection', function(socket) {
  console.log("unix pipe connected");
});