【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が生成されます。