【问题标题】:Using npm package ssh2 within an Angular2 application running under electron在电子下运行的 Angular2 应用程序中使用 npm 包 ssh2
【发布时间】:2016-12-10 17:24:22
【问题描述】:

我想创建一个使用 npm 包 ssh2 - https://www.npmjs.com/package/ssh2 的 Angular2 服务。

我已经按照我的预期安装和配置了它 - 我的服务的代码如下所示(此代码基于 ssh2 npm 站点和 github repo 上显示的第一个示例(唯一的变化是我使用的是密码而不是用于身份验证的密钥)):

const Client = require('ssh2').Client;
const fs = require('fs');

import { NextObserver } from 'rxjs/Observer';
import { Observable } from 'rxjs/Rx';

export class SSHClient {
    username: string;
    password: string;
    host: string;
    port: number;
    ssh: any;

    constructor() {
    }

    init(username, password, host, port) {
        console.log("initiating SSH connection to:" + host + "on port:" + port);

        this.username = username;
        this.password = password;
        this.host = host;
        this.port = port;


        console.log("Connecting now...");
        var conn = new Client();
        conn.on('ready', function() {
          console.log('Client :: ready');
          conn.exec('uptime', function(err, stream) {
            if (err) throw err;
            stream.on('close', function(code, signal) {
              console.log('Stream :: close :: code: ' + code + ', signal: ' + signal);
              conn.end();
            }).on('data', function(data) {
              console.log('STDOUT: ' + data);
            }).stderr.on('data', function(data) {
              console.log('STDERR: ' + data);
            });
          });
        }).connect({
          host: this.host,
          port: this.port,
          username: this.username,
          password: this.password
        });
        console.log("SSH Client created and demo has run");
    }

}

我在我的组件中按此调用服务:

this.ssh.init("username","password","my.little.host",22);

并且我希望通过控制台获取在我的服务器上通过 SSH 执行的 uptime 命令的输出。然而,而不是那个 - 我得到这个:

EXCEPTION: Uncaught (in promise): Error: Error in ./ServerBrowserComponent class ServerBrowserComponent_Host - inline template:0:0 caused by: Cannot read property 'connect' of undefined
TypeError: Cannot read property 'connect' of undefined
    at SSHClient.init (file:///Users/myapp/build/app.js:40259:12)
    at new ServerBrowserComponent (file:///Users/myapp/build/app.js:34158:19)
    at new Wrapper_ServerBrowserComponent (/AppModule/ServerBrowserComponent/wrapper.ngfactory.js:7:18)
    at DebugAppView._View_ServerBrowserComponent_Host0.createInternal (/AppModule/ServerBrowserComponent/host.ngfactory.js:16:38)
    at DebugAppView.AppView.create (file:///Users/myapp/build/app.js:27754:26)
    at DebugAppView.create (file:///Users/myapp/build/app.js:27954:49)
    at ComponentFactory.create (file:///Users/myapp/build/app.js:24393:41)
    at ViewContainerRef_.createComponent (file:///Users/myapp/build/app.js:23441:50)
    at RouterOutlet.activate (file:///Users/myapp/build/app.js:72709:45)
    at ActivateRoutes.placeComponentIntoOutlet (file:///Users/myapp/build/app.js:72207:21)
ORIGINAL STACKTRACE:
Error: Uncaught (in promise): Error: Error in ./ServerBrowserComponent class ServerBrowserComponent_Host - inline template:0:0 caused by: Cannot read property 'connect' of undefined
TypeError: Cannot read property 'connect' of undefined
    at SSHClient.init (ssh.service.ts:49)
    at new ServerBrowserComponent (server.browser.component.ts:31)
    at new Wrapper_ServerBrowserComponent (wrapper.ngfactory.js:7)
    at DebugAppView._View_ServerBrowserComponent_Host0.createInternal (host.ngfactory.js:16)
    at DebugAppView.AppView.create (core.umd.js:9170)
    at DebugAppView.create (core.umd.js:9370)
    at ComponentFactory.create (core.umd.js:5809)
    at ViewContainerRef_.createComponent (core.umd.js:4857)
    at RouterOutlet.activate (router.umd.js:3457)
    at ActivateRoutes.placeComponentIntoOutlet (router.umd.js:2955)
    at resolvePromise (zone-node.js:468)
    at zone-node.js:445
    at ZoneDelegate.invoke (zone-node.js:232)
    at Object.onInvoke (core.umd.js:6206)
    at ZoneDelegate.invoke (zone-node.js:231)
    at Zone.run (zone-node.js:114)
    at zone-node.js:502
    at ZoneDelegate.invokeTask (zone-node.js:265)
    at Object.onInvokeTask (core.umd.js:6197)
    at ZoneDelegate.invokeTask (zone-node.js:264)
Unhandled Promise rejection: Error in ./ServerBrowserComponent class ServerBrowserComponent_Host - inline template:0:0 caused by: Cannot read property 'connect' of undefined ; Zone: angular ; Task: Promise.then ; Value: ViewWrappedError TypeError: Cannot read property 'connect' of undefined
    at SSHClient.init (file:///Users/myapp/build/app.js:40259:12)
    at new ServerBrowserComponent (file:///Users/myapp/build/app.js:34158:19)
    at new Wrapper_ServerBrowserComponent (/AppModule/ServerBrowserComponent/wrapper.ngfactory.js:7:18)
    at DebugAppView._View_ServerBrowserComponent_Host0.createInternal (/AppModule/ServerBrowserComponent/host.ngfactory.js:16:38)
    at DebugAppView.AppView.create (file:///Users/myapp/build/app.js:27754:26)
    at DebugAppView.create (file:///Users/myapp/build/app.js:27954:49)
    at ComponentFactory.create (file:///Users/myapp/build/app.js:24393:41)
    at ViewContainerRef_.createComponent (file:///Users/myapp/build/app.js:23441:50)
    at RouterOutlet.activate (file:///Users/myapp/build/app.js:72709:45)
    at ActivateRoutes.placeComponentIntoOutlet (file:///Users/myapp/build/app.js:72207:21)
Error: Uncaught (in promise): Error: Error in ./ServerBrowserComponent class ServerBrowserComponent_Host - inline template:0:0 caused by: Cannot read property 'connect' of undefined(…)

其中大部分似乎都在挣扎,因为:Cannot read property 'connect' of undefined——但我正在关注示例文档。有人可以帮助我理解为什么这不起作用 - 以及我该如何解决它?

我试图将代码从我的项目中提取出来并放入它自己的文件中,如下所示:

    const Client = require('ssh2').Client; 
console.log("Connecting now...");
         var conn = new Client();
         conn.on('ready', function() {
          console.log('Client :: ready');
          conn.exec('uptime', function(err, stream) {
            if (err) throw err;
            stream.on('close', function(code, signal) {
                 console.log('Stream :: close :: code: ' + code + ', signal: ' + signal);
                  conn.end();
            }).on('data', function(data) {
                  console.log('STDOUT: ' + data);
            }).stderr.on('data', function(data) {
                  console.log('STDERR: ' + data);
            });
          });
       }).connect({
          host: 'my.little.host',
          port: 22,
          username: 'uname',
          password: 'pwd'
        });
         console.log("SSH Client created and demo has run");

但我得到了同样的错误:

 var conn = new Client();
                ^

ReferenceError: Client is not defined
    at Object.<anonymous> (/Users/myapp/attempt.js:2:21)
    at Module._compile (module.js:541:32)
    at Object.Module._extensions..js (module.js:550:10)
    at Module.load (module.js:458:32)
    at tryModuleLoad (module.js:417:12)
    at Function.Module._load (module.js:409:3)
    at Module.runMain (module.js:575:10)
    at run (node.js:348:7)
    at startup (node.js:140:9)
    at node.js:463:3

所以这里出了点简单的问题,可能是什么!?

【问题讨论】:

  • 你安装的是什么版本的ssh2
  • "ssh2": "^0.5.4",
  • 如果您只对它自己进行测试(没有类、导出等),相同的ssh2 代码是否有效?
  • Acutally no - 我得到完全相同的错误 - 请参阅上面的更新问题
  • 您似乎缺少const Client = require('ssh2').Client 行。

标签: node.js angular ssh npm angular-services


【解决方案1】:

ssh2-package 用于 node.js,而不是前端/web。

浏览器不能这样使用网络(electron 使用两个进程,浏览器/渲染器-进程无法访问您需要的网络功能)

你的电子应用有 main.js 文件吗?

这就是您需要实现 ssh 功能的地方。

即在主进程中,而不是在渲染器进程中。

http://electron.atom.io/docs/tutorial/quick-start/#main-process

【讨论】:

  • 所以进程对象可以访问http等但不能访问ssh?
  • 是的,渲染器本质上是一个chrome浏览器,chrome中不能做ssh所以这里也不能做
  • 啊,好的,我试试这个,并使用渲染器 ipc 在客户端和服务器端之间来回切换!
【解决方案2】:

在我的 ssh2 (ssh2shell) 包装器中,我在类的构造函数中有 this.connection = new require('ssh2')();,或者它可以放在 init 函数中。在实例中创建它可能会有所帮助。

"use strict";

class SSHClient {
    constructor() {}

    init(username, password, host, port) {
        console.log("initiating SSH connection to:" + host + "on port:" + port);
        var ssh = require('ssh2').Client
        this._conn = new ssh();

        console.log("Connecting");

        console.log('Client :: ready');
        var self = this
        this._conn.on('ready', function() {
            self._conn.exec('uptime', function(err, stream) {
                if (err) throw err;

                stream.on('data', function(data) {
                    console.log('STDOUT: ' + data);
                }).stderr.on('data', function(data) {
                    console.log('STDERR: ' + data);
                }).on('close', function(code, signal) {
                    console.log('Stream :: close :: code: ' + code + ', signal: ' + signal);
                    self._conn.end();
                });
            });
        }).connect({
            host: host,
            port: port,
            username: username,
            password: password
        });

        console.log("SSH Client created and demo has run");
    }
}
module.exports = SSHClient

或者使用我的package ssh2shell,ssh 连接实例位于 ssh2shell 实例的 sope 中,因此您不必担心。

"use strict";

class SSHClient {
    constructor() {}

    init(username, password, host, port) {
        console.log("initiating SSH connection to:" + host + "on port:" + port);

        var host = {
            server: {     
                host:         host,
                port:         port,
                userName:     username,
                password:     password
                },
            commands:      [ "uptime" ]
        }

        var SSH2Shell = require ('ssh2shell'),

            //Use a callback function to handle the response text
            callback = function(sessionText){
                console.log("SSH Client created and demo has run");
                console.log("Response:\n" + sessionText)
            }

        //Create a new instance passing in the host object
        this._conn = new SSH2Shell(host)

        //Start the process
        this._conn.connect(callback);
    }
}

module.exports = SSHClient

【讨论】:

  • 根据您的第一个建议,我收到错误消息:只能使用 'new' 关键字调用 void 函数。在'this._conn = new require('ssh2')();'行——我也认为你有几个错别字 this_conn 而不是 this._conn。无论哪种方式,它都不会编译我的打字稿。当我尝试您的第二个示例时,出现编译错误 - 请参阅此要点:gist.github.com/renegadeandy/85930e0ce06cf02612f298d0615927f8 - 请注意这里的警告看起来不健康?
  • 我会把它放到一个测试文件中,看看我得到了什么。
  • 使用适用于我的测试环境的代码更新了示例。导出类对我不起作用,我修复了主机对象中的拼写错误和 {} 错误。我有一些未定义的错误,但我在原始代码或测试中的示例中都看不到它为什么是未定义的,这没有帮助。一种选择是 console.log 客户端和 conn 变量以查看返回的内容。
  • 那么从您的示例中,我将如何使用它并通过服务或以我可以在角度组件中使用的方式公开?理想情况下,它需要由服务包装
  • 这是一个新问题吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-03-09
  • 2018-02-12
  • 2020-12-31
  • 1970-01-01
  • 2020-12-04
  • 2017-04-19
  • 1970-01-01
相关资源
最近更新 更多