【Unity】SSH.NETを使ってLinuxServerを動かしてみた

UnityでSSH.Netを使ってLinux Serverを動かしてみたので、方法をまとめます。iOS、Androidの実機テスト済みです。

環境

Mac OS Catalina 10.15.5

Unity 2019.3.13f1

Linux server (今回はAzureでVMを作成しました)

Linux (ubuntu 18.04)

SSH.NET-2016.1.0-bin.zip

導入方法

① Unityを起動し、AssetにPluginsフォルダを作ります。

② ↓のサイトから、SSH.NET-2016.1.0-bin.zipをダウンロードし、SSH.NETファイルをPluginsフォルダにドラッグします。

SSH.NET/lib の中にあるフォルダのうち、net40またはnet35以外のフォルダを削除し、フォルダを一つだけの状態にします。(僕はnet40だけを残しました)

④ 適当にC#ファイルを作り、Visual Studioから作ったファイルを開きます。

⑤ ソリューションを開き、作ったファイルを見つけ、ファイル名を「link.xml」に変更します。これで、ファイル形式が.csから.xmlに変更されます。

⑥ 以下のコードをlink.xmlにコピーします。

<linker>
 <assembly fullname="Renci.SshNet">
   <type fullname="Renci.SshNet.Security.KeyExchangeDiffieHellmanGroupExchangeSha256" preserve="all" />
 </assembly>
</linker>

参考

コード

以下のリンクのコードを真似て作りました。詳しい動作確認はこっちの方がわかりやすいと思います。

Unity用に若干訂正したコードも載せておきます。

ServerInfo.cs

using Renci.SshNet;
using UnityEngine;
namespace SSHNET
{
   public class ServerInfo : MonoBehaviour
   {
       public static SshClient ssh;
   }
}

SSHStartUp.cs

using System;
using System.Collections.Generic;
using Renci.SshNet;
using UnityEngine;
using UnityEngine.UI;
public class SSHStartUp : MonoBehaviour
{
   /// <summary>
   /// 接続先のホスト名またはIPアドレス
   /// </summary>
   public string hostNameOrIpAddr;
   /// <summary>
   /// 接続先のポート番号
   /// </summary>
   public int portNo = 22;
   /// <summary>
   /// ログインユーザー名
   /// </summary>
   public string userName;
   /// <summary>
   /// ログインパスワード
   /// </summary>
   public string passWord;
   public static SshClient ssh;
   // Start is called before the first frame update
   void Start()
   {
       if (String.IsNullOrEmpty(hostNameOrIpAddr) || String.IsNullOrEmpty(userName) || String.IsNullOrEmpty(passWord))
       {
           Debug.LogError("SSH data is null. Please input these data!");
           return;
       }
       try
       {
           // コネクション情報
           ConnectionInfo info = new ConnectionInfo(hostNameOrIpAddr, portNo, userName,
               new AuthenticationMethod[] {
                       new PasswordAuthenticationMethod(userName, passWord)
                   /* PrivateKeyAuthenticationMethod("キーの場所")を指定することでssh-key認証にも対応しています */
               }
           );
           // クライアント作成
           SSHNET.ServerInfo.ssh = new SshClient(info);
           // 接続開始
           SSHNET.ServerInfo.ssh.Connect();
           if (SSHNET.ServerInfo.ssh.IsConnected)
           {
               // 接続に成功した(接続状態である)
               Debug.Log("[OK] SSH Connection succeeded!!");

               GameObject Text = GameObject.Find("Text");
               Text.GetComponent<Text>().text = "[OK] SSH Connection succeeded!!";
           }
           else
           {
               // 接続に失敗した(未接続状態である)
               Debug.LogError("[NG] SSH Connection failed!!");
               return;
           }
       }
       catch (Exception ex)
       {
           // エラー発生時
           Debug.LogError(ex);
           throw ex;
       }
   }
   // Update is called once per frame
   void Update()
   {
   }
}

VMCommand.cs

using System;
using System.Collections;
using System.Collections.Generic;
using Renci.SshNet;
using UnityEngine;

namespace SSHNET
{
   public class VMCommand : MonoBehaviour
   {
       /// <summary>
       /// Run command.
       /// </summary>
       /// <param name="commandString">送信したいコマンド</param>
       /// <returns></returns>
       public static bool runCommand(string commandString)
       {
           bool result = true;
           try
           {
               // コマンドを作成する
               SshCommand cmd = ServerInfo.ssh.CreateCommand(commandString);
               // コマンドを実行する
               Debug.LogFormat("[CMD] {0}", commandString);
               cmd.Execute();
               // 結果を変数に入れる
               var stdOut = cmd.Result;
               var stdErr = cmd.Error;
               // 終了コードを表示する
               Debug.LogFormat("終了コード:{0}", cmd.ExitStatus);
               // 標準出力を表示する
               if (stdOut != string.Empty)
               {
                   Debug.Log("標準出力:");
                   Debug.Log(stdOut);
                   return true;
               }
               // エラー出力を表示する
               if (cmd.ExitStatus != 0 && stdErr != string.Empty)
               {
                   Debug.LogError("標準エラー出力:");
                   Debug.LogError(stdErr);
                   return false;
               }
           }
           catch (Exception ex)
           {
               // エラー発生時
               Debug.LogError(ex);
               //throw ex;
               return false;
           }
           return result;
           }
       }
   }

CommandRunner.cs

using System;
using System.Collections;
using System.Collections.Generic;
using Renci.SshNet;
using UnityEngine;
using UnityEngine.UI;
public class CommandRunner : MonoBehaviour
{
   public Button runCommandButton;
   // Start is called before the first frame update
   void Start()
   {
       runCommandButton.onClick.AddListener(onClickRunCommandButton);
   }
   // Update is called once per frame
   void Update()
   {
       
   }
   void onClickRunCommandButton()
   {
       bool result = SSHNET.VMCommand.runCommand("ffmpeg -i Downloads/img1.jpg -s 1920:1080 -q 2 Downloads/output.jpg");
       runCommandButton.GetComponentInChildren<Text>().text
           = result ? "Success" : "Failed";
   }
}

設定

① Create Empty よりGameObject を作成し、SSHStartUp.csとCommandRunner.csをドラッグします。

② GameObjectの SSH Start UpにIPアドレス、ポートナンバー、ユーザ名、パスワードを入力します。

③ UIよりボタンを設置し、Command Runnerに設置します。

④ Linuxサーバのダウンロードフォルダにimg1.jpgを用意します。

④は動作のテストとして画像をリサイズするffmpegコマンドを使用する場合必要です。コマンドの内容はCommandRunner.cs/onClickRunCommandButton/SSHNET.VMCommand.runCommand の変数を変えることで変更できます。

結果

Linux サーバのダウンロードフォルダにoutput.jpgが生成されます。

いいなと思ったら応援しよう!