2016-08-30 1 views
0

Я использую следующий код, чтобы попытаться отправить сообщения OSC на компьютер в сети. Я использую пакет под названием osc.Невозможно отправить сообщения OSC с пакетом osc узла. Ошибка при закрытии порта, несмотря на то, что порт на машине открыт

Я не могу отправить сообщения в машине, выполняющей OSC сервер и получить ошибку ниже при попытке отправить OSC сообщения:

Error: Uncaught, unspecified "error" event. (Can't send packets on a closed osc.Port object. Please open (or reopen) this Port by calling open().) 

код

let osc = require('osc'); 

let oscUDP = new osc.UDPPort({ 
    remoteAddress: "192.168.1.5", 
    remotePort: 8004 
}); 

oscUDP.send({ 
    address: "/carrier/frequency", 
    args: 440 
}); 

oscUDP.open(); 

Если я ставлю oscUDP.open() до send звонок Я получаю иную ошибку:

Error: send EINVAL 192.168.1.5:8004 
at Object.exports._errnoException (util.js:1007:11) 
at exports._exceptionWithHostPort (util.js:1030:20) 
at SendWrap.afterSend [as oncomplete] (dgram.js:402:11) 

Я запускаю OSCulator на OSX в качестве сервера. Приведенный выше код живет на другой машине. Когда я бегу nmap по IP-адресу порт открыт:

nmap 192.168.1.5 -p 8004 

Starting Nmap 6.40 (http://nmap.org) at 2016-08-30 08:22 BST 
Nmap scan report for 192.168.1.5 
Host is up (0.13s latency). 
PORT  STATE SERVICE 
8004/tcp open unknown 

Если я использую osc-cli сообщения поступают на машине, работающей на OSC сервер:

osc --host 192.168.1.5:8004 /test 1 2 3 

Так, казалось бы, проблему ISN 't с закрытыми портами вообще, поскольку сообщения отправляются и принимаются при использовании osc-cli.

Любые идеи?

ответ

1

Я понял, что на самом деле довольно легко отправлять данные OSC по UDP без необходимости в каких-либо пакетах, кроме a2r-osc, который используется для кодирования данных OSC.

Я отправляю решение закончит кому-либо еще в заинтересованы:

const dgram = require('dgram'); 
const client = dgram.createSocket('udp4'); 
const osc = require('a2r-osc'); 

const HOST = '192.168.1.5'; 
const PORT = 8004; 

process.on('SIGINT', function() { 
    client.close(); 
}); 

let noteOn = function(note) { 
    return new osc.Message('/note/' + note, 'i', 1).toBuffer(); 
} 

let noteOff = function(note) { 
    return new osc.Message('/note/' + note, 'i', 0).toBuffer(); 
} 

let send = function(message) { 
    client.send(message, PORT, HOST, function(err, bytes) { 
    if(err) throw new Error(err); 
    }) 
} 

send(noteOn('c')); 
setTimeout(function() { 
    send(noteOff('c')); 
}, 1000); 
3

Я знаю, что я иду на это довольно поздно, и это выглядит, как вы нашли другую библиотеку, которая работает для вас, но я подумал, что ответ может быть полезен для тех, кто сталкивается с этой проблемой. Я разработчик osc.js, оригинальной библиотеки, которую вы пытались использовать.

Во-первых, в качестве справочной информации, osc.js раскладывается на два разных слоя:

  1. с низким уровнем API, который обеспечивает функции для чтения и записи OSC сообщений и пакетов в/из типизированных массивов.
  2. Чем выше уровень, на основе события порта API, который предоставляет набор транспортных объектов для конкретных платформ, которые предлагают простой способ сделать двунаправленную связь по протоколам UDP, как, веб-сокеты и т.д.

В случае вашего примера кода вы пытались отправить сообщение OSC на свой объект UDPPort до его готовности. Когда вы open() a Port, возможно, потребуется выполнить асинхронные операции, такие как открытие сокета и т. Д. В результате он запускает событие (точно названное ready), когда порт настроен для использования. До ready пожаров вы не сможете отправлять или получать пакеты OSC.

Таким образом, в случае исходного кода, он выглядит, как вы были в предположении, что эта линия была синхронной, и что вы могли бы назвать send() сразу после этого:

oscUDP.open(); 

Вместо этого, вы просто нужно слушать для ready перед попыткой отправить сообщение на Port. Пример:

oscUDP.on("ready", function() { 
    oscUDP.send({ 
     address: "/carrier/frequency", 
     args: 440 
    }); 
}); 

osc.js Node.js example иллюстрирует этот шаблон. Но когда я увидел ваш вопрос, я понял, что пример кода в osc.js README был немного неоднозначным в этом отношении. У меня есть improved the event documentation и the inline README sample code, чтобы быть более ясными в этом отношении. Извините за путаницу.

Есть случаи, возможно, такие как ваши, где API более высокого уровня не совсем то, что вам нужно. osc.js также предоставляет функции для легкого кодирования пакета OSC как Uint8Array, которые могут быть преобразованы в буферы Node.js. Таким образом, вы могли бы сделать что-то похожее на свое решение, просто используя функцию osc.js 'osc.writeMessage(). К счастью, он всегда был хорошо документирован. Вот ваш пример, модифицированный для использования низкоуровневого API osc.js':

const dgram = require('dgram'); 
const client = dgram.createSocket('udp4'); 
const osc = require('osc'); 

const HOST = '192.168.1.5'; 
const PORT = 8004; 

process.on('SIGINT', function() { 
    client.close(); 
}); 

let oscNoteMessage = function(note, value) { 
    var message = osc.writeMessage({ 
     address: '/note/' + note, 
     args: [ 
      { 
       type: 'i', 
       value: value 
      } 
     ] 
    }); 

    return Buffer.from(message); 
} 

let noteOn = function(note) { 
    return oscNoteMessage(note, 1); 
} 

let noteOff = function(note) { 
    return oscNoteMessage(note, 0); 
} 

let send = function(message) { 
    client.send(message, PORT, HOST, function(err, bytes) { 
    if(err) throw new Error(err); 
    }) 
} 

send(noteOn('c')); 
setTimeout(function() { 
    send(noteOff('c')); 
}, 1000); 

Во всяком случае, я рад, что вы были в состоянии придумать решение, которое работает для вашего проекта, и я надеюсь, что этот ответ поможет другим пользователям, которые могут столкнуться с подобными проблемами. И, конечно, не стесняйтесь задавать вопросы или проблемы с файлом на osc.js issue tracker.

С уважением, и извинения за возникшую у вас проблемы с использованием библиотеки!

Смежные вопросы