123
This commit is contained in:
@@ -16,47 +16,109 @@ namespace NetPanel.Bl
|
||||
private string _pwd = "";
|
||||
private string _host = "";
|
||||
|
||||
private SshClient client = null;
|
||||
/// <summary>
|
||||
/// 客户端
|
||||
/// </summary>
|
||||
private SshClient _client = null;
|
||||
/// <summary>
|
||||
/// sell
|
||||
/// </summary>
|
||||
private ShellStream _shellStream = null;
|
||||
/// <summary>
|
||||
/// 读取流
|
||||
/// </summary>
|
||||
private StreamReader _reader = null;
|
||||
/// <summary>
|
||||
/// 写入流
|
||||
/// </summary>
|
||||
private StreamWriter _writer = null;
|
||||
|
||||
public SshBl(string host, string username, string pwd)
|
||||
/// <summary>
|
||||
/// 是否连接完成
|
||||
/// </summary>
|
||||
private bool _isConnected = false;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// ssh连接
|
||||
/// </summary>
|
||||
/// <param name="host">ip</param>
|
||||
/// <param name="username">登录用户</param>
|
||||
/// <param name="pwd">登录密码</param>
|
||||
/// <param name="columns">单元格</param>
|
||||
/// <param name="rows">行</param>
|
||||
/// <param name="width">宽</param>
|
||||
/// <param name="height">高</param>
|
||||
public SshBl(string host, string username, string pwd, uint columns, uint rows, uint width, uint height)
|
||||
{
|
||||
_username = username;
|
||||
_pwd = pwd;
|
||||
_host = host;
|
||||
client = new SshClient(host, username, pwd);
|
||||
client.Connect();
|
||||
_client = new SshClient(host, username, pwd);
|
||||
_client.Connect();
|
||||
if (_client.IsConnected)
|
||||
{
|
||||
_shellStream = _client.CreateShellStream("xterm", columns, rows, width, height, 1024);
|
||||
_reader = new StreamReader(_shellStream);
|
||||
_writer = new StreamWriter(_shellStream);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 单条读取,可循环读取
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
|
||||
public StreamReader RunCommand(string command)
|
||||
public string ReadLine()
|
||||
{
|
||||
|
||||
var sshCommand = client.CreateCommand(command);
|
||||
var asyncExecute = sshCommand.BeginExecute();
|
||||
|
||||
return new StreamReader(sshCommand.OutputStream);
|
||||
//string outStr;
|
||||
//while ((outStr = reader.ReadLine()) != null)
|
||||
//{
|
||||
|
||||
//}
|
||||
return _reader.ReadLine();
|
||||
}
|
||||
|
||||
public string ServerVersion()
|
||||
/// <summary>
|
||||
/// 写入命令
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
|
||||
public void WriteLine(string line)
|
||||
{
|
||||
return client.ConnectionInfo.ServerVersion;
|
||||
|
||||
_writer.WriteLine(line);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 全部读取,可循环读取
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public string ReadToEnd()
|
||||
{
|
||||
return _reader.ReadToEnd();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Ssh 客户端
|
||||
/// </summary>
|
||||
public SshClient Client { get { return _client; } }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 关闭
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
client.Disconnect();
|
||||
client.Dispose();
|
||||
|
||||
if (_writer != null) _writer.Close();
|
||||
if (_reader != null) _reader.Close();
|
||||
//if (_shellStream != null) _shellStream.Close();
|
||||
if (_shellStream != null) _shellStream.Dispose();
|
||||
|
||||
if (_client != null) { _client.Disconnect(); _client.Dispose(); }
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.SignalR;
|
||||
using NetPanel.Bl;
|
||||
|
||||
using NetPanel.Help;
|
||||
using Renci.SshNet;
|
||||
using System.Diagnostics;
|
||||
using System.Text;
|
||||
|
||||
namespace NetPanel.Controllers.SSH
|
||||
@@ -9,14 +11,43 @@ namespace NetPanel.Controllers.SSH
|
||||
public class SSHController : Controller
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public IActionResult SSH()
|
||||
|
||||
public async Task<IActionResult> SSH()
|
||||
{
|
||||
|
||||
//SshBl sshBl = new SshBl("172.31.110.239", "root", "123456789");
|
||||
//SshBl sshBl = new SshBl("172.29.119.239", "root", "123456789", 80, 24, 800, 600);
|
||||
|
||||
|
||||
|
||||
//var output = sshBl.ReadLine();
|
||||
|
||||
//sshBl.WriteLine("top");
|
||||
//int cc = 0;
|
||||
//while (true)
|
||||
//{
|
||||
// var outpu3 = sshBl.Read();
|
||||
|
||||
// if (cc == 0)
|
||||
// {
|
||||
// await Task.Delay(5000);
|
||||
// sshBl.WriteLine("\x03");
|
||||
|
||||
// cc = 1;
|
||||
// }
|
||||
// else if (cc == 2)
|
||||
// {
|
||||
// break;
|
||||
// }
|
||||
|
||||
//}
|
||||
|
||||
|
||||
|
||||
//sshBl.Dispose();
|
||||
|
||||
////string tt = sshBl.ServerVersion();
|
||||
//StringBuilder sbStr = new StringBuilder();
|
||||
//string tt = "";
|
||||
@@ -47,6 +78,6 @@ namespace NetPanel.Controllers.SSH
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
using Microsoft.AspNetCore.SignalR;
|
||||
using NetPanel.Bl;
|
||||
using NetPanel.Entity;
|
||||
using NetPanel.Help;
|
||||
using Renci.SshNet.Common;
|
||||
using Renci.SshNet.Messages;
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Net.Sockets;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
|
||||
@@ -10,6 +16,15 @@ namespace NetPanel.SignalR
|
||||
public class ChatHub : Hub
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// ssh 管理
|
||||
/// </summary>
|
||||
private static Dictionary<string, SshBl> dicSsh = new Dictionary<string, SshBl>();
|
||||
|
||||
/// <summary>
|
||||
/// 建立连接时
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override async Task OnConnectedAsync()
|
||||
{
|
||||
|
||||
@@ -25,30 +40,114 @@ namespace NetPanel.SignalR
|
||||
await client.SendAsync("ConnectionId", rm);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 断开异步时
|
||||
/// </summary>
|
||||
/// <param name="exception"></param>
|
||||
/// <returns></returns>
|
||||
|
||||
public async Task<ReturnMsg> CreateConnectionAsync(string connectionId, string command)
|
||||
public override async Task OnDisconnectedAsync(Exception? ex)
|
||||
{
|
||||
var cid = Context.ConnectionId;
|
||||
if (dicSsh.ContainsKey(cid))
|
||||
{
|
||||
dicSsh[cid].Dispose();
|
||||
dicSsh.Remove(cid);
|
||||
}
|
||||
await base.OnDisconnectedAsync(ex);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建终端链接
|
||||
/// </summary>
|
||||
/// <param name="connectionId"></param>
|
||||
/// <param name="command"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<ReturnMsg> CreateConnectionAsync(uint width, uint height, uint columns, uint rows)
|
||||
{
|
||||
|
||||
var cid = Context.ConnectionId;
|
||||
ReturnMsg rm = new ReturnMsg();
|
||||
rm.Code = 1;
|
||||
if (!dicSsh.ContainsKey(cid))
|
||||
{
|
||||
SshBl ssh = new SshBl("172.29.119.239", "root", "123456789", columns, rows, width, height);
|
||||
dicSsh.Add(cid, ssh);
|
||||
ReceiveMessage(cid);
|
||||
}
|
||||
return rm;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 写入命令
|
||||
/// </summary>
|
||||
/// <param name="curr_line"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<ReturnMsg> WriteLineAsync(string curr_line)
|
||||
{
|
||||
ReturnMsg rm = new ReturnMsg();
|
||||
rm.Code = 1;
|
||||
|
||||
//SshBl sshBl = new SshBl("172.31.110.239", "root", "123456789");
|
||||
////string tt = sshBl.ServerVersion();
|
||||
//StringBuilder sbStr = new StringBuilder();
|
||||
//string tt = "";
|
||||
//var reader = sshBl.RunCommand("top");
|
||||
//string outStr = null;
|
||||
//while ((outStr = reader.ReadLine()) != null)
|
||||
//{
|
||||
// sbStr.Append(outStr + "/r/n");
|
||||
//}
|
||||
rm.Obj = "====>" + command;
|
||||
//根据id获取指定客户端
|
||||
var client = Clients.Client(connectionId);
|
||||
|
||||
// await client.SendAsync("CreateConnectionAsync", rm);
|
||||
|
||||
|
||||
var cid = Context.ConnectionId;
|
||||
if (dicSsh.ContainsKey(cid))
|
||||
{
|
||||
dicSsh[cid].WriteLine(curr_line);
|
||||
ReceiveMessage(cid);
|
||||
}
|
||||
return rm;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 发送响应
|
||||
/// </summary>
|
||||
/// <param name="ssh"></param>
|
||||
/// <returns></returns>
|
||||
public async Task ReceiveMessage(string cid)
|
||||
{
|
||||
ReturnMsg rm = new ReturnMsg();
|
||||
rm.Code = 1;
|
||||
int count = 0;
|
||||
SshBl ssh = dicSsh[cid];
|
||||
//根据id获取指定客户端
|
||||
var client = Clients.Client(cid);
|
||||
while (true)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
string line = ssh.ReadLine();
|
||||
if (line.IsNotNull())
|
||||
{
|
||||
if (line.Contains(":~#"))
|
||||
{
|
||||
rm.Code = 2; ;
|
||||
rm.Obj = line;
|
||||
await client.SendAsync("ReceiveMessage", rm);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
rm.Obj = line + "\n";
|
||||
await client.SendAsync("ReceiveMessage", rm);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
await Task.Delay(100);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,8 +49,8 @@
|
||||
convertEol: true, //启用时,光标将设置为下一行的开头
|
||||
disableStdin: false, //是否应禁用输入。
|
||||
theme: {
|
||||
foreground: 'yellow', //字体
|
||||
background: '#060101', //背景色
|
||||
// foreground: 'yellow', //字体
|
||||
// background: '#060101', //背景色
|
||||
cursor: 'help',//设置光标
|
||||
}
|
||||
});
|
||||
@@ -58,9 +58,15 @@
|
||||
// 获取窗口的宽度和高度。
|
||||
const width = window.innerWidth;
|
||||
const height = window.innerHeight;
|
||||
const columns = parseInt(width / 10);
|
||||
const rows = parseInt(height / 22);
|
||||
|
||||
//cursorx 这个长度不能删除,用于ev.keyCode === 8
|
||||
var cursorx = 0;
|
||||
|
||||
|
||||
// 调整终端的尺寸。
|
||||
term.resize(parseInt(width / 10), parseInt(height / 22));
|
||||
term.resize(columns, parseInt(height / 22));
|
||||
|
||||
//回车输入的内容
|
||||
var curr_line = '';
|
||||
@@ -71,30 +77,38 @@
|
||||
var connectionId = '';
|
||||
|
||||
term.open(document.getElementById('terminal'));
|
||||
|
||||
|
||||
term.prompt = () => {
|
||||
term.write('\n\u001b[32m$ >\u001b[37m');
|
||||
};
|
||||
|
||||
|
||||
//通讯
|
||||
var connection = new signalR.HubConnectionBuilder().withUrl("/chatHub").build();
|
||||
|
||||
|
||||
//signalR接收消息
|
||||
connection.on("ReceiveMessage", function (user, message) {
|
||||
term.write(message);
|
||||
connection.on("ReceiveMessage", function (msg) {
|
||||
term.write(msg.obj);
|
||||
|
||||
});
|
||||
|
||||
|
||||
//获取通讯id
|
||||
// 已建立连接
|
||||
connection.on("ConnectionId", function (msg) {
|
||||
|
||||
term.write('Welcome to my Scheme web intepreter!\r\n123');
|
||||
term.prompt();
|
||||
// term.write('Welcome to my Scheme web intepreter!\r\n123');
|
||||
// term.prompt();
|
||||
connectionId = msg.obj;
|
||||
//创建 ssh 客户端
|
||||
connection.invoke('CreateConnectionAsync', width, height, columns, rows).then((result) => {
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// 监听后端终端关闭
|
||||
connection.on('WriteErrorAsync', () => {
|
||||
|
||||
@@ -104,26 +118,26 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
term.on('key', function (key, ev) {
|
||||
|
||||
|
||||
const printable = !ev.altKey && !ev.altGraphKey && !ev.ctrlKey && !ev.metaKey
|
||||
//const printable = !e.domEvent.altKey && !e.domEvent.altGraphKey && !e.domEvent.ctrlKey && !e.domEvent.metaKey;
|
||||
|
||||
if (cursorx == 0) {
|
||||
cursorx = term.buffer.cursorX;
|
||||
}
|
||||
if (ev.keyCode === 13) { // Enter key
|
||||
if (curr_line.replace(/^\s+|\s+$/g, '').length != 0) { // Check if string is all whitespace
|
||||
entries.push(curr_line);
|
||||
currPos = entries.length - 1;
|
||||
// term.prompt();
|
||||
|
||||
connection.invoke('CreateConnectionAsync', connectionId, curr_line).then((result) => {
|
||||
if (result.code == 1) {
|
||||
//term.prompt();
|
||||
//term.write(result.obj);
|
||||
|
||||
term.write('\n' + result.obj);
|
||||
term.prompt();
|
||||
connection.invoke('WriteLineAsync', curr_line).then((result) => {
|
||||
if (result.code == 1) {
|
||||
|
||||
// term.write('\n' + result.obj);
|
||||
// term.prompt();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -133,7 +147,7 @@
|
||||
}
|
||||
curr_line = '';
|
||||
} else if (ev.keyCode === 8) { // Backspace
|
||||
if (term.buffer.cursorX > 3) {
|
||||
if (term.buffer.cursorX > cursorx) {
|
||||
curr_line = curr_line.slice(0, -1);
|
||||
term.write('\b \b');
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user