【问题标题】:NodeJS dbus not workingNodeJS dbus 不工作
【发布时间】:2014-11-22 23:36:22
【问题描述】:

我正在尝试通过 DBus 使用 NodeJS 从 omxplayer 获取状态,为此我只是尝试执行 shell 脚本:

    #!/bin/bash
    #set -x
    OMXPLAYER_DBUS_ADDR="/tmp/omxplayerdbus"
    OMXPLAYER_DBUS_PID="/tmp/omxplayerdbus.pid"
    export DBUS_SESSION_BUS_ADDRESS=`cat $OMXPLAYER_DBUS_ADDR`
    export DBUS_SESSION_BUS_PID=`cat $OMXPLAYER_DBUS_PID`
    [ -z "$DBUS_SESSION_BUS_ADDRESS" ] && { echo "Must have DBUS_SESSION_BUS_ADDRESS" >&2; exit 1; }
    duration=`dbus-send --print-reply=literal --session --reply-timeout=500 --dest=org.mpris.MediaPlayer2.omxplayer /org/mpris/MediaPlayer2 org.freedesktop.DBus.Properties.Duration`
    [ $? -ne 0 ] && exit 1
    duration="$(awk '{print $2}' <<< "$duration")"
    position=`dbus-send --print-reply=literal --session --reply-timeout=500 --dest=org.mpris.MediaPlayer2.omxplayer /org/mpris/MediaPlayer2 org.freedesktop.DBus.Properties.Position`
    [ $? -ne 0 ] && exit 1
    position="$(awk '{print $2}' <<< "$position")"
    playstatus=`dbus-send --print-reply=literal --session --reply-timeout=500 --dest=org.mpris.MediaPlayer2.omxplayer /org/mpris/MediaPlayer2 org.freedesktop.DBus.Properties.PlaybackStatus`
    [ $? -ne 0 ] && exit 1
    playstatus="$(sed 's/^ *//;s/ *$//;' <<< "$playstatus")"
    paused="true"
    [ "$playstatus" == "Playing" ] && paused="false"
    echo "Duration: $duration"
    echo "Position: $position"
    echo "Paused: $paused"
    ;;

var exec = require('child_process').exec;
exec('bash status.sh', function() {
    console.log(arguments);
})

但它会打印出来

    { '0':
       { [Error: Command failed: Failed to open connection to "session" message bus: Did not receive a reply. Possible causes include: the remote application did not send a reply, the message bus security policy blocked the reply, the reply timeout expired, or the network connection was broken.
       ] killed: false, code: 1, signal: null },
      '1': '',
      '2': 'Failed to open connection to "session" message bus: Did not receive a reply. Possible causes include: the remote application did not send a reply, the message bus security policy blocked the reply, the reply timeout expired, or the network connection was broken.\n' }

当我直接在控制台中执行该脚本时,它可以工作。 NodeJS 在树莓派上运行。

更新:

我也尝试过“node-dbus”和“dbus-native”模块,但它们都不适合我,但也许我用错了?执行

dbus-send --print-reply=literal --session --reply-timeout=500 --dest=org.mpris.MediaPlayer2.omxplayer /org/mpris/MediaPlayer2 org.freedesktop.DBus.Properties.Duration

我用过 dbus 原生

    var exec = require('child_process').exec;
    exec('cat /tmp/omxplayerdbus', function(error, data, stderr) {
        data = data.replace("\n",'');
        var dbus = require('dbus-native');
        var bus = dbus.sessionBus({
            busAddress: data //unix:abstract=/tmp/dbus-7BuZanKhmv,guid=7fafe7baa2d38357478f04ff5429712a
        });
        bus.invoke({
            path: '/org/mpris/MediaPlayer2',
            destination: 'org.mpris.MediaPlayer2.omxplayer',
            'interface': 'org.freedesktop.DBus.Properties.Position'
        }, function(err, res) {
            console.log(arguments);
        });
        //And this
        var conn = dbus({
            busAddress: data
        });
        conn.message({
            path:'/org/mpris/MediaPlayer2',
            destination: 'org.mpris.MediaPlayer2.omxplayer',
            type: dbus.messageType.methodCall
        });
        conn.on('message', function(msg) { console.log(msg); }).on('error', function() {
            console.log(arguments);
        }).on('connect', function() {
            console.log(arguments);
        });
    });

这两种方法都会给我这个错误:

    events.js:72
            throw er; // Unhandled 'error' event
                  ^
    Error: write EPIPE
        at errnoException (net.js:904:11)
        at Object.afterWrite (net.js:720:19)

更新 2

我现在正在使用“dbus-native”模块,但仍然不断收到“EPIPE”错误。我检查了“Handshake.js”,一切正常,所以我转储了标准输入和标准输出消息:

    {stdin}AUTH EXTERNAL 30

    {stdout}OK df028c4a159a4db39ccc41c0542b9e3b

    {stdin}BEGIN

    {stdin}lmo/org/freedesktop/DBussorg.freedesktop.DBussHellosorg.freedesktop.DBus
    PuTTY{stdin}l5�o/org/mpris/MediaPlayer2sorg.freedesktop.DBus.PropertiessGets org.mpris.MediaPlayer2.omxplayegss org.mpris.MediaPlayer2.omxplayePosition

{stdout} - 标准输出消息行 {stdin} - 标准输入消息行

然后是“EPIPE”。

更新 3

我发现在第一个 dbus "DATA" 命令之后立即抛出 "EPIPE" 错误,在这种情况下是

lmo/org/freedesktop/DBussorg.freedesktop.DBussHellosorg.freedesktop.DBus PuTTY{stdin}l5�o/org/mpris/MediaPlayer2sorg.freedesktop.DBus.PropertiessGets org.mpris.MediaPlayer2.omxplayegss org.mpris.MediaPlayer2.omxplayePosition

我是通过 dbus 进行通信的新手,但根据 DBus protocol,应该发送消息 DATA &lt;data in hex encoding&gt;,但 dbus-native 发送的消息没有 DATA 命令名称。

【问题讨论】:

  • 您是否尝试过任何现有的节点库(我是其中一个 dbus-native 的作者)?
  • 感谢您的回复,我已经更新了我的问题。
  • 看起来无法连接到该地址。尝试使用 echo -e "\0AUTH ANONYMOUS \r\n" | socat abstract-client:/tmp/dbus-7BuZanKhmv - 之类的 socat 进行测试
  • Socat 打印出exactly 2 addresses required (there are 1),当我添加第二个参数时,它打印出unknown device/address。第二个参数应该是什么地址?尝试了很多组合。
  • 最后一个“-”是第二个地址(stdout),socat将数据从stdin转发到dbus,从dbus转发到stdout。

标签: node.js bash shell raspberry-pi dbus


【解决方案1】:

您正在尝试使用 properties api 读取 dbus 对象属性。注意 dbus-send 的最后一个参数是 interface.member,所以你发送的消息是

var bus = dbus.sessionBus({ busAddress: fs.readFileSync('/tmp/omxplayerdbus', 'ascii').trim()})
bus.invoke({
  path: "/org/mpris/MediaPlayer2",
  interface: "org.freedesktop.DBus.Properties",
  member: "Get",
  destination: "org.mpris.MediaPlayer2.omxplayer",
  signature: "ss",
  body: [
    "org.mpris.MediaPlayer2.omxplayer",
    "Position"
  ]
}, function(err, position) {
  console.log(err, position);
});

【讨论】:

  • 感谢您的解释,但在使用调用方法时我仍然不断收到EPIPE 错误。错误来自abstractsocket/node_modules/exec_stream/index.js child.stdin.on('error') 事件。在 Handshake.js 中一切正常,它执行AUTH EXTERNAL 30 并接收OK。我更新了我的问题,添加了更多详细信息(请参阅“更新 2”)。
  • 看起来 dbus 在握手期间断开连接,不知道为什么。
  • 当我注释掉消息发送方法时,连接永远保持活动状态,没有错误。但是在发送第一条消息后,它会引发错误。
  • 这可能是因为握手不完整,如果不正确,服务器会断开连接。你可以尝试使用 master 的 dbus-native 并运行github.com/sidorares/node-dbus/blob/master/bin/dbus-dissect.js 来监控通信吗?
  • 我已经更新dbus-natvie并运行dbus-dissect.js,但由于process.env.DBUS_SESSION_BUS_ADDRESS未定义,所以我临时分配地址给fs.readFileSync('/tmp/omxplayerdbus', 'ascii').trim()然后启动dbus客户端,但客户端总是打印输出 Didn't write bytes to closed stream 并剖析打印件 Server started...
猜你喜欢
  • 2015-06-12
  • 1970-01-01
  • 2019-09-04
  • 2023-03-23
  • 2016-11-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多