diff --git a/NetPanel.Bl/SshBl.cs b/NetPanel.Bl/SshBl.cs
index b42cc7b..8e22fdb 100644
--- a/NetPanel.Bl/SshBl.cs
+++ b/NetPanel.Bl/SshBl.cs
@@ -16,47 +16,109 @@ namespace NetPanel.Bl
private string _pwd = "";
private string _host = "";
- private SshClient client = null;
+ ///
+ /// 客户端
+ ///
+ private SshClient _client = null;
+ ///
+ /// sell
+ ///
+ private ShellStream _shellStream = null;
+ ///
+ /// 读取流
+ ///
+ private StreamReader _reader = null;
+ ///
+ /// 写入流
+ ///
+ private StreamWriter _writer = null;
- public SshBl(string host, string username, string pwd)
+ ///
+ /// 是否连接完成
+ ///
+ private bool _isConnected = false;
+
+
+
+
+
+ ///
+ /// ssh连接
+ ///
+ /// ip
+ /// 登录用户
+ /// 登录密码
+ /// 单元格
+ /// 行
+ /// 宽
+ /// 高
+ 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);
+ }
}
+ ///
+ /// 单条读取,可循环读取
+ ///
+ ///
- 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()
+ ///
+ /// 写入命令
+ ///
+ ///
+
+ public void WriteLine(string line)
{
- return client.ConnectionInfo.ServerVersion;
-
+ _writer.WriteLine(line);
}
+
+ ///
+ /// 全部读取,可循环读取
+ ///
+ ///
+ public string ReadToEnd()
+ {
+ return _reader.ReadToEnd();
+ }
+
+
+ ///
+ /// Ssh 客户端
+ ///
+ public SshClient Client { get { return _client; } }
+
+
///
/// 关闭
///
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(); }
+
}
}
}
diff --git a/NetPanel/Controllers/SSH/SSHController.cs b/NetPanel/Controllers/SSH/SSHController.cs
index 7590b22..d651cf4 100644
--- a/NetPanel/Controllers/SSH/SSHController.cs
+++ b/NetPanel/Controllers/SSH/SSHController.cs
@@ -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 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
-
+
}
}
diff --git a/NetPanel/SignalR/ChatHub.cs b/NetPanel/SignalR/ChatHub.cs
index a1779ca..d701871 100644
--- a/NetPanel/SignalR/ChatHub.cs
+++ b/NetPanel/SignalR/ChatHub.cs
@@ -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
{
+ ///
+ /// ssh 管理
+ ///
+ private static Dictionary dicSsh = new Dictionary();
+
+ ///
+ /// 建立连接时
+ ///
+ ///
public override async Task OnConnectedAsync()
{
@@ -25,30 +40,114 @@ namespace NetPanel.SignalR
await client.SendAsync("ConnectionId", rm);
}
+ ///
+ /// 断开异步时
+ ///
+ ///
+ ///
- public async Task 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);
+ }
+
+ ///
+ /// 创建终端链接
+ ///
+ ///
+ ///
+ ///
+ public async Task 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;
+ }
+
+ ///
+ /// 写入命令
+ ///
+ ///
+ ///
+ public async Task 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;
}
+
+
+
+
+ ///
+ /// 发送响应
+ ///
+ ///
+ ///
+ 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)
+ {
+ }
+ }
+
+
+
+
+ }
+
+
}
}
diff --git a/NetPanel/Views/SSH/SSH.cshtml b/NetPanel/Views/SSH/SSH.cshtml
index ec07a45..b238536 100644
--- a/NetPanel/Views/SSH/SSH.cshtml
+++ b/NetPanel/Views/SSH/SSH.cshtml
@@ -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');
}