Compare commits
1
Commits
0.7.2.0
...
Dev/NamedPipe
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
76cb528eb4 |
No files matched your search
@@ -5,6 +5,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Fleck" Version="1.0.3" />
|
||||
<PackageReference Include="MvvmLightLibs" Version="5.4.1" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
@@ -1,11 +1,16 @@
|
||||
using FluentTerminal.App.Services;
|
||||
using Fleck;
|
||||
using FluentTerminal.App.Services;
|
||||
using FluentTerminal.Models;
|
||||
using FluentTerminal.Models.Enums;
|
||||
using GalaSoft.MvvmLight;
|
||||
using GalaSoft.MvvmLight.Command;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.IO.Pipes;
|
||||
using System.Linq;
|
||||
using System.Net.NetworkInformation;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FluentTerminal.App.ViewModels
|
||||
@@ -30,6 +35,8 @@ namespace FluentTerminal.App.ViewModels
|
||||
private readonly IApplicationView _applicationView;
|
||||
private readonly IDispatcherTimer _resizeOverlayTimer;
|
||||
private readonly IClipboardService _clipboardService;
|
||||
private IWebSocketConnection _webSocket;
|
||||
private NamedPipeClientStream _namedPipe;
|
||||
|
||||
public TerminalViewModel(int id, ISettingsService settingsService, ITrayProcessCommunicationService trayProcessCommunicationService, IDialogService dialogService,
|
||||
IKeyboardCommandService keyboardCommandService, ApplicationSettings applicationSettings, string startupDirectory, ShellProfile shellProfile,
|
||||
@@ -187,7 +194,37 @@ namespace FluentTerminal.App.ViewModels
|
||||
DefaultTitle = response.ShellExecutableName;
|
||||
Title = DefaultTitle;
|
||||
|
||||
await _terminalView.ConnectToSocket(response.WebSocketUrl).ConfigureAwait(true);
|
||||
_namedPipe = new NamedPipeClientStream(".", response.PipeName, PipeDirection.InOut, PipeOptions.None);
|
||||
if (!_namedPipe.IsConnected)
|
||||
{
|
||||
_namedPipe.Connect();
|
||||
}
|
||||
|
||||
var webSocketUrl = "ws://127.0.0.1:" + response.Port;
|
||||
var webSocketServer = new WebSocketServer(webSocketUrl);
|
||||
webSocketServer.Start(socket =>
|
||||
{
|
||||
_webSocket = socket;
|
||||
socket.OnOpen = () =>
|
||||
{
|
||||
Console.WriteLine("open");
|
||||
//_connectedEvent.Set();
|
||||
};
|
||||
socket.OnClose = () =>
|
||||
{
|
||||
Console.WriteLine("closing");
|
||||
_namedPipe.Close();
|
||||
};
|
||||
socket.OnMessage = message =>
|
||||
{
|
||||
var bytes = Encoding.UTF8.GetBytes(message);
|
||||
_namedPipe.Write(bytes, 0, bytes.Length);
|
||||
};
|
||||
});
|
||||
|
||||
ListenToNamedPipe();
|
||||
|
||||
await _terminalView.ConnectToSocket(webSocketUrl).ConfigureAwait(true);
|
||||
Initialized = true;
|
||||
}
|
||||
else
|
||||
@@ -198,6 +235,26 @@ namespace FluentTerminal.App.ViewModels
|
||||
await FocusTerminal().ConfigureAwait(true);
|
||||
}
|
||||
|
||||
private void ListenToNamedPipe()
|
||||
{
|
||||
Task.Run(async () =>
|
||||
{
|
||||
var reader = new StreamReader(_namedPipe);
|
||||
do
|
||||
{
|
||||
var offset = 0;
|
||||
var buffer = new char[1024];
|
||||
var readChars = await reader.ReadAsync(buffer, offset, buffer.Length - offset);
|
||||
if (readChars > 0)
|
||||
{
|
||||
await _webSocket.Send(new String(buffer));
|
||||
}
|
||||
}
|
||||
while (!reader.EndOfStream);
|
||||
_webSocket.Close();
|
||||
});
|
||||
}
|
||||
|
||||
private async Task InvokeCloseRequested()
|
||||
{
|
||||
if (_applicationSettings.ConfirmClosingTabs)
|
||||
@@ -311,5 +368,34 @@ namespace FluentTerminal.App.ViewModels
|
||||
ShowSearchPanel = false;
|
||||
_terminalView.FocusTerminal();
|
||||
}
|
||||
|
||||
private const int FirstDynamicPort = 49151;
|
||||
|
||||
public static int? GetAvailablePort()
|
||||
{
|
||||
var usedPorts = new List<int>();
|
||||
|
||||
var properties = IPGlobalProperties.GetIPGlobalProperties();
|
||||
|
||||
var connections = properties.GetActiveTcpConnections();
|
||||
usedPorts.AddRange(connections.Where(c => c.LocalEndPoint.Port >= FirstDynamicPort).Select(c => c.LocalEndPoint.Port));
|
||||
|
||||
var endPoints = properties.GetActiveTcpListeners();
|
||||
usedPorts.AddRange(endPoints.Where(e => e.Port >= FirstDynamicPort).Select(e => e.Port));
|
||||
|
||||
endPoints = properties.GetActiveUdpListeners();
|
||||
usedPorts.AddRange(endPoints.Where(e => e.Port >= FirstDynamicPort).Select(e => e.Port));
|
||||
|
||||
usedPorts.Sort();
|
||||
|
||||
for (var i = FirstDynamicPort; i < UInt16.MaxValue; i++)
|
||||
{
|
||||
if (!usedPorts.Contains(i))
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,8 +4,9 @@
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public bool Success { get; set; }
|
||||
public string WebSocketUrl { get; set; }
|
||||
public int Port { get; set; }
|
||||
public string Error { get; set; }
|
||||
public string ShellExecutableName { get; set; }
|
||||
public string PipeName { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,8 @@
|
||||
using Fleck;
|
||||
using FluentTerminal.Models;
|
||||
using FluentTerminal.Models;
|
||||
using FluentTerminal.Models.Requests;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.IO.Pipes;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using static winpty.WinPty;
|
||||
@@ -18,7 +16,7 @@ namespace FluentTerminal.SystemTray.Services
|
||||
private IntPtr _handle;
|
||||
private Stream _stdin;
|
||||
private Stream _stdout;
|
||||
private IWebSocketConnection _webSocket;
|
||||
private NamedPipeServerStream _outServer;
|
||||
|
||||
public TerminalSession(CreateTerminalRequest request)
|
||||
{
|
||||
@@ -72,29 +70,17 @@ namespace FluentTerminal.SystemTray.Services
|
||||
|
||||
Id = port.Value;
|
||||
_connectedEvent = new ManualResetEventSlim(false);
|
||||
WebSocketUrl = "ws://127.0.0.1:" + port;
|
||||
var webSocketServer = new WebSocketServer(WebSocketUrl);
|
||||
webSocketServer.Start(socket =>
|
||||
{
|
||||
_webSocket = socket;
|
||||
socket.OnOpen = () =>
|
||||
{
|
||||
Console.WriteLine("open");
|
||||
_connectedEvent.Set();
|
||||
};
|
||||
socket.OnClose = () =>
|
||||
{
|
||||
Console.WriteLine("closing");
|
||||
ConnectionClosed?.Invoke(this, EventArgs.Empty);
|
||||
};
|
||||
socket.OnMessage = message =>
|
||||
{
|
||||
var bytes = Encoding.UTF8.GetBytes(message);
|
||||
_stdin.Write(bytes, 0, bytes.Length);
|
||||
};
|
||||
});
|
||||
|
||||
PipeName = @"LOCAL\" + Guid.NewGuid().ToString();
|
||||
|
||||
_outServer = new NamedPipeServerStream(PipeName, PipeDirection.InOut, 1, PipeTransmissionMode.Byte, PipeOptions.None);
|
||||
|
||||
StreamReader reader = new StreamReader(_outServer);
|
||||
|
||||
|
||||
|
||||
ListenToStdOut();
|
||||
ListenToNamedPipe();
|
||||
}
|
||||
|
||||
~TerminalSession()
|
||||
@@ -114,7 +100,9 @@ namespace FluentTerminal.SystemTray.Services
|
||||
public event EventHandler ConnectionClosed;
|
||||
|
||||
public int Id { get; }
|
||||
public string WebSocketUrl { get; }
|
||||
|
||||
public string PipeName { get; }
|
||||
|
||||
public string ShellExecutableName { get; }
|
||||
|
||||
public void Dispose()
|
||||
@@ -178,12 +166,18 @@ namespace FluentTerminal.SystemTray.Services
|
||||
return pipe;
|
||||
}
|
||||
|
||||
private void ListenToStdOut()
|
||||
private void ListenToNamedPipe()
|
||||
{
|
||||
new NotificationService().ShowNotification("DEBUG", "wating now");
|
||||
_outServer.WaitForConnection();
|
||||
new NotificationService().ShowNotification("DEBUG", "connected");
|
||||
|
||||
Task.Run(async () =>
|
||||
{
|
||||
_connectedEvent.Wait();
|
||||
var reader = new StreamReader(_stdout);
|
||||
//_connectedEvent.Wait();
|
||||
var reader = new StreamReader(_outServer);
|
||||
var writer = new StreamWriter(_stdin);
|
||||
|
||||
do
|
||||
{
|
||||
var offset = 0;
|
||||
@@ -191,12 +185,34 @@ namespace FluentTerminal.SystemTray.Services
|
||||
var readChars = await reader.ReadAsync(buffer, offset, buffer.Length - offset);
|
||||
if (readChars > 0)
|
||||
{
|
||||
await _webSocket.Send(new String(buffer));
|
||||
writer.Write(buffer, 0, readChars);
|
||||
}
|
||||
}
|
||||
while (!reader.EndOfStream);
|
||||
_webSocket.Close();
|
||||
_stdin.Close();
|
||||
});
|
||||
}
|
||||
|
||||
private void ListenToStdOut()
|
||||
{
|
||||
Task.Run(async () =>
|
||||
{
|
||||
var reader = new StreamReader(_stdout);
|
||||
var writer = new StreamWriter(_outServer);
|
||||
|
||||
do
|
||||
{
|
||||
var offset = 0;
|
||||
var buffer = new char[1024];
|
||||
var readChars = await reader.ReadAsync(buffer, offset, buffer.Length - offset);
|
||||
if (readChars > 0)
|
||||
{
|
||||
writer.Write(buffer, 0, readChars);
|
||||
}
|
||||
}
|
||||
while (!reader.EndOfStream);
|
||||
_outServer.Close();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -35,7 +35,8 @@ namespace FluentTerminal.SystemTray.Services
|
||||
{
|
||||
Success = true,
|
||||
Id = terminal.Id,
|
||||
WebSocketUrl = terminal.WebSocketUrl,
|
||||
Port = Utilities.GetAvailablePort().Value,
|
||||
PipeName = terminal.PipeName,
|
||||
ShellExecutableName = terminal.ShellExecutableName
|
||||
};
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user