Node.js
Ubuntu
RaspberryPi
IoT
GoogleHome

google-home-notifierの「Error: getaddrinfo -3008」に対処する

More than 1 year has passed since last update.


はじめに

緊急地震速報をGoogle Homeでアナウンスしてみよう と、Ubuntu14.04でgoogle-home-notifierを実行したところ、

Error: getaddrinfo -3008

が発生しました。以下、その時に行った内容のメモ書きになります。


browser.js の修正 :confounded:

いつものアレだ と、google-home-notifierAfter "npm install" に従い、node_modules/mdns/lib/browser.js へ {families:[4]} を追加しました。


browser.js.diff

--- browser.js  (revision x)

+++ browser.js (working copy)
@@ -116,7 +116,7 @@

Browser.defaultResolverSequence = [
rst.DNSServiceResolve()
-, 'DNSServiceGetAddrInfo' in dns_sd ? rst.DNSServiceGetAddrInfo() : rst.getaddrinfo()
+, 'DNSServiceGetAddrInfo' in dns_sd ? rst.DNSServiceGetAddrInfo() : rst.getaddrinfo({families:[4]})
, rst.makeAddressesUnique()
];

ところが、結果は変わらず、エラー発生。Raspberry Piなどでは改善したのだけど...、違うのか。

Raspberry PI 2 getaddrinfo 3008 error #130 内のコメントにあった {families:[0]} なども試してみましたが、これもダメ...。


IPアドレスを指定 :anguished:

node_modules/google-home-notifier/google-home-notifier.js を確認してみると、Google HomeのIPアドレスを指定すれば、mdnsを使わないことが分かりました。実際、

const googlehome = require('google-home-notifier')

googlehome.device('Google-Home', 'ja');
googlehome.ip('192.168.xxx.xxx'); //Google HomeのIPアドレスを指定
googlehome.notify('こんにちは。私はグーグルホームです。', function(res) {
console.log(res);
});

といった感じにすれば、エラーは回避できました。でも、できればIPアドレスは指定したくない...。


google-home-notifier.js の修正 :grinning:

結局のところ、Google HomeのIPアドレスを別の方法で取得すればよいのか、ということで、Google Homeの名前とIPアドレスを検出する方法 を参考にしました(ありがとうございます)。そちらでは multicast-dns を利用していたので、node_modules/google-home-notifier/google-home-notifier.js を以下のように修正しました。


google-home-notifier.js.diff

--- google-home-notifier.js (revision x)

+++ google-home-notifier.js (working copy)
@@ -1,7 +1,6 @@
var Client = require('castv2-client').Client;
var DefaultMediaReceiver = require('castv2-client').DefaultMediaReceiver;
-var mdns = require('mdns');
-var browser = mdns.createBrowser(mdns.tcp('googlecast'));
+var mdns = require('multicast-dns')()
var deviceAddress;
var language;

@@ -25,17 +24,28 @@

var notify = function(message, callback) {
if (!deviceAddress){
- browser.start();
- browser.on('serviceUp', function(service) {
- console.log('Device "%s" at %s:%d', service.name, service.addresses[0], service.port);
- if (service.name.includes(device.replace(' ', '-'))){
- deviceAddress = service.addresses[0];
+ mdns.on('response', function (response) {
+ var name = '';
+ var ip = '';
+ for (const additional of response.additionals) {
+ if (additional.type == 'TXT') name = additional.name;
+ if (additional.type == 'A') ip = additional.data;
+ }
+ console.log('Device "%s" at %s', name, ip);
+ if (name.includes(device.replace(' ', '-'))){
+ deviceAddress = ip;
getSpeechUrl(message, deviceAddress, function(res) {
callback(res);
});
+ mdns.destroy();
}
- browser.stop();
});
+
+ mdns.query('_googlecast._tcp.local', 'PTR');
+
+ setTimeout(function () {
+ mdns.destroy();
+ }, 2500);
}else {
getSpeechUrl(message, deviceAddress, function(res) {
callback(res);


とりあえずはこの修正で動いているようです(IPアドレスを指定することなく)。最初に応答のあったGoogle Homeのみに通知しているので、オリジナルとは動作が異なる気がしますが...。


おわりに

今回は場当たり的な対処しか行わなかったので、時間が出来たら根本の原因を調査してみようと思います(調査ってどうやるのだろう...)。