Ngrok развертывает приложение онлайн, результат всегда пустC#

Место общения программистов C#
Ответить Пред. темаСлед. тема
Anonymous
 Ngrok развертывает приложение онлайн, результат всегда пуст

Сообщение Anonymous »

Я хочу протестировать grpc онлайн через Интернет. Для этой цели мне нужно туннелировать мой ноутбук, чтобы к локальному grpc можно было получить доступ через Интернет с помощью программы ngrok.
Я скачал ngrok.exe с сайта https://dashboard.ngrok.com/get-started/setup/windows
Процесс аутентификации всегда завершается успешно, когда я тестировал с помощью C# (шаг 1),
но при развертывании приложения в Интернете результат всегда пустой (шаг 2)?
using CardData.Ext.Logger;
using CustomerCardServer.Ext.Mod.General;
using CustomerCardServer.Properties;
using System.Diagnostics;
using System.Text;
using System.Text.RegularExpressions;
using File = System.IO.File;

namespace CustomerCardServer.Ext.Mod.Tunnel
{

public class NgrokTunnelManager
{
private static NgrokTunnelManager? _instance;
private static object _instanceLocker = new object();

private String? _appPath;
private String? _ngrokTunnelFile;
private String? _cmdFile;

private List _processIDs = new List();
public List ProcessIDs
{
get { return _processIDs; }
private set { _processIDs = value; }
}

public String? SessionStatus { get; private set; }
public String? PublicUrl { get; private set; }
public String? PrivateUrl { get; private set; }

private NgrokTunnelManager()
{
CopyCmdPromptFile();
CopyNgrokTunnelFile();
}

public static NgrokTunnelManager GetInstance()
{
if (_instance is null)
{
lock (_instanceLocker)
{
_instance = new NgrokTunnelManager();
}
}
return _instance;
}

public bool CopyNgrokTunnelFile()
{
try
{
// App path
_appPath = Application.StartupPath;
if (String.IsNullOrEmpty(_appPath))
{
MessageBox.Show("AppPath isn't valid!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
// ngrok file
_ngrokTunnelFile = _appPath + Common.NGROK_NAME;
if (String.IsNullOrEmpty(_ngrokTunnelFile))
{
MessageBox.Show("Devtunnel.exe isn't found!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
// create ngrok file
if (!File.Exists(_ngrokTunnelFile))
{
File.WriteAllBytes(_ngrokTunnelFile, Resources.ngrok);
}
// save ngrok file path
Settings.Default.NgrokFile = _ngrokTunnelFile;
Settings.Default.Save();
return true;
}
catch (Exception ex)
{
Log.Exception(ex);
}
return false;
}

public bool CopyCmdPromptFile()
{
try
{
// App path
_appPath = Application.StartupPath;
if (String.IsNullOrEmpty(_appPath))
{
MessageBox.Show("AppPath isn't valid!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
// cmd shortcut file
_cmdFile = _appPath + Common.CMD_NAME;
if (String.IsNullOrEmpty(_cmdFile))
{
MessageBox.Show("Cmd.exe isn't found!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
// create cmd shortcut file
if (!File.Exists(_cmdFile))
{
File.WriteAllBytes(_cmdFile, Resources.cmd);
}
// save cmd shortcut file path
Settings.Default.CmdFile = _cmdFile;
Settings.Default.Save();
return true;
}
catch (Exception ex)
{
Log.Exception(ex);
}
return false;
}

public async Task AuthAlsoStartAsync(String authToken, String ipAddress, int port)
{
try
{
var argument1 = $"ngrok config add-authtoken {authToken}";
var argument2 = $"ngrok http https://{ipAddress}:{port}";

var authResult = await RunCommandAsync(argument1, TimeSpan.FromSeconds(5));
if (!authResult.Contains("Authtoken saved to configuration file"))
{
return false;
}

// BUG IN HERE, startResult IS ALWAYS EMPTY?
var startResult = await RunCommandAsync(argument2, TimeSpan.FromSeconds(5));
if (String.IsNullOrEmpty(startResult))
{
return false;
}

// Regex to extract Session Status
String? sessionStatus = Regex.Match(startResult, @"Session Status\s+(\w+)").Groups[1].Value;

// Regex to extract Forwarding URLs
Match? forwardingMatch = Regex.Match(startResult, @"Forwarding\s+(https?://[^\s]+)\s+->\s+(https?://[^\s]+)");
String? publicUrl = forwardingMatch.Groups[1].Value;
String? privateUrl = forwardingMatch.Groups[2].Value;

if (!String.IsNullOrEmpty(sessionStatus) && !String.IsNullOrEmpty(publicUrl) && !String.IsNullOrEmpty(privateUrl))
{
SessionStatus = sessionStatus;
PublicUrl = publicUrl;
PrivateUrl = privateUrl;
return true;
}
}
catch (Exception ex)
{
Log.Exception(ex);
}
return false;
}

private int GetNgrokTunnelProcessId(string processName)
{
try
{
// Get the list of processes with the specified name
Process[] processes = Process.GetProcessesByName(processName);
if (processes.Length > 0)
{
// Return the PID of the first process found
return processes[0].Id;
}
return -1; // Process not found
}
catch (Exception ex)
{
Log.Exception(ex);
}
return -1;
}

private void StopProcess()
{
try
{
// kill current devtunnel
Process[] processes = Process.GetProcessesByName(Path.GetFileNameWithoutExtension(Common.NGROK_NAME));
foreach (Process process in processes)
{
if (process is null)
{
continue;
}
if (_processIDs is null)
{
break;
}
if (_processIDs.Count == 0)
{
break;
}
if (_processIDs.Contains(process.Id))
{
process.Kill();
}
}
}
catch (Exception ex)
{
Log.Exception(ex);
}
}

public async Task RunCommandAsync(String argument, TimeSpan timeout, bool isInputEnable = false)
{
try
{
StopProcess();

var startInfo = new ProcessStartInfo
{
FileName = "cmd.exe",
Arguments = $"/c {argument}",
RedirectStandardOutput = true,
RedirectStandardInput = true,
RedirectStandardError = true,
UseShellExecute = false,
CreateNoWindow = true,
};

var process = new Process()
{
StartInfo = startInfo,
EnableRaisingEvents = true // Enable raising events to handle process exit
};

var tcs = new TaskCompletionSource();
var fgThread = new Thread(() =>
{
var result = RunCommandXAsync(process, timeout, isInputEnable).ConfigureAwait(false).GetAwaiter().GetResult();
tcs.SetResult(result);
});
fgThread.IsBackground = false;
fgThread.SetApartmentState(ApartmentState.STA);
fgThread.Start();
fgThread.Join();

return tcs.Task.ConfigureAwait(false).GetAwaiter().GetResult();
}
catch (Exception ex)
{
Log.Exception(ex);
}
return String.Empty;
}

public async Task RunCommandXAsync(Process process, TimeSpan timeout, bool isInputEnable = false)
{
try
{
var tcsExit = new TaskCompletionSource();

var errorBuilder = new StringBuilder();
var outputBuilder = new StringBuilder();

// Event handler for error
process.ErrorDataReceived += (sender, e) =>
{
if (!String.IsNullOrEmpty(e.Data))
{
errorBuilder.AppendLine(e.Data);
}
};

// Event handler for output
process.OutputDataReceived += (sender, e) =>
{
if (!String.IsNullOrEmpty(e.Data))
{
outputBuilder.AppendLine(e.Data);
}
};

// Event handler for exit
process.Exited += (sender, e) =>
{
if (tcsExit.Task.IsCompleted)
{
tcsExit = new TaskCompletionSource();
}
tcsExit.TrySetResult(process.ExitCode);
};

bool isProcessStarted = process.Start();
if (!isProcessStarted)
{
return String.Empty;
}

// Start the asynchronous read of the error stream.
process.BeginErrorReadLine();

// Start the asynchronous read of the output stream.
process.BeginOutputReadLine();

// Add process id devtunnel.exe
Thread.Sleep(TimeSpan.FromSeconds(2));
int processId = GetNgrokTunnelProcessId(Path.GetFileNameWithoutExtension(Common.NGROK_NAME));
if (processId != -1)
{
if (!_processIDs.Contains(processId))
{
_processIDs.Add(processId);
}
}

Task taskCompleted = await Task.WhenAny(tcsExit.Task, Task.Delay(timeout));
if (taskCompleted.IsCompletedSuccessfully)
{
var error = errorBuilder.ToString();
if (!String.IsNullOrEmpty(error))
{
// error
return error;
}

// output
var output = outputBuilder.ToString();
if (!String.IsNullOrEmpty(output))
{
// input
if (isInputEnable)
{
if (output.Contains("Are you sure? y/n"))
{
using (var writer = process.StandardInput)
{
if (writer is not null)
{
_ = writer.WriteLineAsync("Y");
writer.Close();
}
}
}
}

// output
return output;
}
}

}
catch (Exception ex)
{
Log.Exception(ex);
}
return String.Empty;
}

}
}

(Шаг 1) Я использую приглашение cmd для вызова ngrok.exe для выполнения аутентификации с помощью приведенной ниже команды:
ngrok config add-authtoken 2kUseW0CrdBjp6pqPcVJzg0UzGq_4g4W8aq34wjDbqRTopiqd

Ожидаемый результат:
Authtoken saved to configuration file:
C:\Users\xxxx\AppData\Local/ngrok/ngrok.yml

(Шаг 2) Я использую приглашение cmd для вызова ngrok.exe для развертывания приложения в Интернете с помощью приведенной ниже команды:
ngrok http https://localhost:8080

Ожидаемый результат:
ngrok (Ctrl+C to quit) Found a bug? Let us know: https://github.com/ngrok/ngrok Session Status online
Account xxxxxxx@gmail.com (Plan: Free)
Version 3.16.0
Region Asia (ap)
Latency 42ms
Web Interface http://127.0.0.1:4040
Forwarding https://fb82-202-154-12-130.ngrok-free.app -> https://127.0.0.1:8080 Connections ttl opn rt1 rt5 p50 p90
0 0 0.00 0.00 0.00 0.00


Подробнее здесь: https://stackoverflow.com/questions/790 ... ways-empty
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C#»