我正在尝试编写一些简约的客户端 - 服务器代码,以便在不同本地网络上的两台计算机之间传递OSC消息。具体来说,我的最终目标是使用MAX的UDPSend和UDPReceive函数发送和接收Ableton中的MAX补丁,这些函数只是在本地端口上侦听。这是服务器代码,我有Ableton的OSC发送MIDI模块发送到。这正确地接收来自第一台计算机的MAX补丁的输出,一些来自通道的MIDI数据。
var osc = require('osc-min'),
dgram = require('dgram');
var remotes = [];
var FileReader = require('fs');
// listen for OSC messages and print them to the console
var udp = dgram.createSocket('udp4', function(msg, rinfo) {
try {
var oscmsg = osc.fromBuffer(msg);
console.log(oscmsg);
remotes.forEach(function(remote, index, array) {
udp.send(msg, 0, oscmsg.length, 10000, remote);
console.log('Sent OSC message to %s:%d', remote, 10000);
});
} catch (err) {
console.log(err);
}
});
FileReader.readFile('ips.txt', 'utf8', function(err, data) {
// By lines
var lines = data.split('\n');
for(var line = 0; line < lines.length; line++){
remotes.push(lines[line]);
}
});
udp.bind(9998);
console.log('Listening for OSC messages on port 9998');
服务器正确获取如下的OSC消息:
{ address: '/Note1',
args: [ { type: 'integer', value: 60 } ],
oscType: 'message' }
然后,我想将计算机1的消息中继到我在端口9998上的远程服务器上发送给我在端口10000上监听的其他计算机。(该服务器是Amazon EC2 Ubuntu实例。)这些计算机的公共IP位于文件ips.txt。
在接收计算机上(在Windows上测试),我设置了一个Node客户端,通过其公共IP接收数据并将其转发到localhost,以便MAX补丁可以看到它。因此,在此计算机上发送到10000的任何消息都将发送到127.0.0.1:9999。
var osc = require('osc-min'),
dgram = require('dgram'),
remote;
// listen for OSC messages and print them to the console
var udp = dgram.createSocket('udp4', function(msg, rinfo) {
try {
var oscmsg = osc.fromBuffer(msg);
console.log(oscmsg);
send(msg);
} catch (err) {
console.log('Could not decode OSC message');
}
});
function send(oscMessage) {
udp.send(oscMessage, 0, oscMessage.length, 9999, "127.0.0.1");
console.log('Sent OSC message to %s:%d', "127.0.0.1", 9999);
}
udp.bind(10000);
console.log('Listening for OSC messages on port 10000');
问题是,服务器的消息似乎永远不会到达客户端。一旦服务器收到消息,它就会产生输出:
Listening for OSC messages on port 9998
{ address: '/Velocity1',
args: [ { type: 'integer', value: 100 } ], oscType: 'message' }
Sent OSC message to client-public-ip:10000
但是客户端只是挂起了它的初始监听状态
Listening for OSC messages on port 10000
我认为这可能是我的防火墙的一个问题,我确保通过端口和所涉及的所有应用程序专门启用UDP,没有任何好处。我希望避免使用HTTPRequests。我非常感谢任何建议。
答案 0 :(得分:1)
Daniel使用WebSockets的解决方案是正确的。但是,我还需要确保通过DNS名称而不是公共IP地址连接客户端。例如:
const WebSocketClient = require('websocket').client;
const port = process.env.PORT || 3000;
const wsc = new WebSocketClient();
wsc.connect('ws://ec2.compute-1.amazonaws.com:4000/', 'echo-protocol');
相反:
wsc.connect('ws://1.2.3.4:4000/', 'echo-protocol');
有关此问题的更多详细信息here。
我还使用了&#39; websocket&#39; npm模块而不是&#39; ws,&#39;但我不确定是否有所作为。
答案 1 :(得分:0)
我发现在不同的局域网之间使用这种方法的最简单方法 WAN用于代理UDP请求,并使用Websockets将它们发送到Echo服务器。这是一个例子:
回应服务器(WAN)
"use strict";
const WebSocket = require('ws');
const port = process.env.PORT || 3000;
const wss = new WebSocket.Server({ port: port });
// Broadcast to all
wss.broadcast = function broadcast(data) {
wss.clients.forEach(function each(client) {
if (client.readyState === WebSocket.OPEN) {
client.send(data);
}
});
};
wss.on('connection', function connection(ws, req) {
const ip = req.connection.remoteAddress;
console.log('connecting to', ip);
ws.on('message', function incoming(data) {
// Broadcast to everyone else.
wss.clients.forEach(function each(client) {
if (client !== ws && client.readyState === WebSocket.OPEN) {
client.send(data);
}
});
});
});
UDP服务器/ WebSocket客户端(本地)
const Buffer = require('buffer').Buffer;
const dgram = require('dgram');
const WebSocketServer = require('ws').Server;
const port = process.env.PORT || 3000;
const wss = new WebSocketServer({port});
//The ip port of the UDP server
var SERVER_IP = '127.0.0.1'
var SERVER_PORT = 11000
wss.on('connection', function(ws) {
//Create a udp socket for this websocket connection
let udpClient = dgram.createSocket('udp4');
//When a message is received from udp server send it to the ws client
udpClient.on('message', function(msg, rinfo) {
ws.send(msg.toString());
});
//When a message is received from ws client send it to UDP server.
ws.on('message', function(message) {
var msgBuff = new Buffer(message);
udpClient.send(msgBuff, 0, msgBuff.length, SERVER_PORT, SERVER_IP);
});
});
<强>测试强>
您可以配置Ableton连接到本地UDP服务器,在此示例中,默认地址类似于udp:// localhost:11000。