You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

树莓派Node.js服务器仅本地可访问,跨网络请求无响应求助

问题:树莓派Node.js服务本地可访问,PC端无法连接
  • 树莓派1上部署的Node.js服务,本地通过https://alfred.local:8080可正常访问(使用终端浏览器lynx测试能获取预期网页)
  • PC端无法加载该服务,已确认以下信息:
    • 域名alfred.local可正确解析至树莓派无线网卡IP地址192.168.68.62
    • PC与树莓派间可通过SSH、VNC正常连通,网络无问题
    • 尝试改用80端口,访问https://alfred.local:80仍无效果

iptables规则(用于排查防火墙问题)

Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain FORWARD (policy DROP)
target     prot opt source               destination
DOCKER-USER  all  --  anywhere             anywhere
DOCKER-ISOLATION-STAGE-1  all  --  anywhere             anywhere
ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED
DOCKER     all  --  anywhere             anywhere
ACCEPT     all  --  anywhere             anywhere
ACCEPT     all  --  anywhere             anywhere

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Chain DOCKER (1 references)
target     prot opt source               destination

Chain DOCKER-ISOLATION-STAGE-1 (1 references)
target     prot opt source               destination
DOCKER-ISOLATION-STAGE-2  all  --  anywhere             anywhere
RETURN     all  --  anywhere             anywhere

Chain DOCKER-ISOLATION-STAGE-2 (1 references)
target     prot opt source               destination
DROP       all  --  anywhere             anywhere
RETURN     all  --  anywhere             anywhere

Chain DOCKER-USER (1 references)
target     prot opt source               destination
RETURN     all  --  anywhere             anywhere

相关配置与代码文件

config.txt

var config = {
  port: '80',
  serial: '/dev/ttyAMA0',
  host: 'alfred.local'
};

config.ssl = {
  key: '/home/alfred/AccentaG4/taiman.co.uk_private_key.key',
  cert:'/home/alfred/AccentaG4/taiman.co.uk_ssl_certificate.cer'
};

config.notify={
  to: 'swchoi.choi@googlemail.com'
}

config.js

const log = require('./log')

const config = () => {
    if (process.argv.length > 2) {
        const config = require(process.argv[2])
        return config
    } else {
        log.error('Configuration file not provided, exiting.')
        process.exit(1)
    }
}

module.exports = config()

alarm.js

const config = require('./config')
const Serial = require('./serial')
const Server = require('./server')
const status = require('./status')
const Notify = require('./notify')
const log = require('./log')

const serial = Serial({
    port: config.serial,
    baudRate: 115200
})

const server = Server({
    port: config.port,
    ssl: config.ssl,
    host: config.host
})

const notify = Notify(config.notify)

notify('Alarm controller started')

status
    .on('link', state =>
        notify(`Alarm panel link ${state ? 'up' : 'down'}`)
    )
    .on('armed', state =>
        notify(`Alarm ${state ? 'armed' : 'disarmed'}`)
    )
    .on('abort', state =>
        notify(`Alarm ${state ? 'aborted' : 'reset'}`)
    )
    .on('intruder', state =>
        notify(state ? 'INTRUDER [!]' : 'Intruder alarm deactivated')
    )
    .on('panic', state =>
        notify(state ? 'PANIC [!]' : 'Panic alarm deactivated')
    )
    .on('autoArm', hour =>
        log.info(`Auto-arm ${hour === -1 ? 'disabled' : `enabled at ${hour}:00`}`)
    )
    .on('autoDisarm', hour =>
        log.info(`Auto-disarm ${hour === -1 ? 'disabled' : `enabled at ${hour}:00`}`)
    )
    .on('autoDays', days =>
        log.info(`Auto-arm/disarm days: ${status.getAutoDays()}`)
    )

status.setAutoArm(config.autoArmHour)
status.setAutoDisarm(config.autoDisarmHour)

serial.listen(message => {
    switch (message.substr(0, 4)) {
    case 'HBT:':
        var staleness = parseInt(message.substring(4), 10)
        // status.update('link', staleness < 120)
        status.setLink(staleness < 120)
        break
    case 'SIG:':
        var signals = message.substring(4)
        status.setArmed(signals.charAt(0) === 'S')
        status.setAbort(signals.charAt(1) === 'A')
        status.setIntruder(signals.charAt(2) === 'I')
        status.setPanic(signals.charAt(3) === 'P')
        break
    case 'AIR:':
        var airQuality = message.substring(4)
        status.setAirQuality(airQuality)
        break
    default:
    }
    server.send(message)
})

server.listen(message => {
    if (message.substring(0, 5) === '#ARM=') {
        status.setAutoArm(parseInt(message.split('=')[1]))
        server.send('ARM:' + status.getAutoArm())
    } else if (message.substring(0, 5) === '#DIS=') {
        status.setAutoDisarm(parseInt(message.split('=')[1]))
        server.send('DIS:' + status.getAutoDisarm())
    } else if (message.substring(0, 5) === '#DAY=') {
        status.toggleAutoDay(parseInt(message.split('=')[1]))
        server.send('DAY:' + status.getAutoDays())
    } else {
        if (message === '?') {
            server.send('ARM:' + status.getAutoArm())
            server.send('DIS:' + status.getAutoDisarm())
            server.send('DAY:' + status.getAutoDays())
        }
        serial.send(message)
    }
})

setInterval(function() {
    var date = new Date()
    if (status.getArmed()) {
        if (config.autoDisarmCode
            && status.isAutoDay(date.getDay())
            && date.getHours() === status.getAutoDisarm()
            && date.getMinutes() === 0) {
            log.info('alarm auto-disarmed')
            serial.send(config.autoDisarmCode)
        }
    } else {
        if (config.autoArmCode
            && status.isAutoDay(date.getDay())
            && date.getHours() === status.getAutoArm()
            && date.getMinutes() === 0) {
            log.info('alarm auto-armed')
            serial.send(config.autoArmCode)
        }
    }
}, 60000)

Server.js

const fs = require('fs')
const https = require('https')
const express = require('express')
const path = require('path')
const WebSocket = require('ws')
const {Subject, merge} = require('rxjs')
const {filter, throttleTime} = require('rxjs/operators')
const {ENABLE_CHAR} = require('./constants')
const log = require('./log')


module.exports = ({port, ssl,host}) => {
    const app = express()

    app.use(express.static(path.join(__dirname, '../client')))

    app.get('/', function(req, res) {
        res.render('index.html')
    })

    const send$ = new Subject()

    const sslCredentials = {
        key: fs.readFileSync(ssl.key || __dirname + '/key.pem'),
        cert: fs.readFileSync(ssl.cert || __dirname + '/cert.pem')
    }

    const server = https.createServer(sslCredentials, app)

    const wss = new WebSocket.Server({server})

    server.listen(port,host,() => {
        log.info(`Server started on ${host} port ${port}`)
    })

    const listen = callback =>
        wss.on('connection', ws =>
            ws.on('message', message =>
                callback(message.toString('utf-8'))
            )
        )

    // const data$ = merge(
    //     send$.pipe(
    //         filter(data => data !== ENABLE_CHAR)
    //     ),
    //     send$.pipe(
    //         filter(data => data === ENABLE_CHAR),
    //         throttleTime(3000)
    //     )
    // )

    send$.subscribe(
        data => {
            // data !== ENABLE_CHAR && log.log('Downstream message:', {data})
            wss.clients.forEach(function (client) {
                if (client.readyState === WebSocket.OPEN) {
                    client.send(data)
                }
            })
        }
    )

    const send = data =>
        send$.next(data)

    return {listen, send}
}

内容的提问来源于stack exchange,提问作者Ageis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 09:15:56