Execute command callback on different thread

Add ConnectingEventArgs to allow more control during connection stage
This commit is contained in:
olegkap_cp
2010-12-15 22:42:56 +00:00
parent ccda04e6f1
commit 04ec42133a
6 changed files with 112 additions and 15 deletions
@@ -3,13 +3,13 @@ namespace Renci.SshClient.Tests
{
public static class ConnectionData
{
public static string Host { get { return "152.54.8.155"; } }
public static string Host { get { return "oleg-centos.edc.renci.org"; } }
public static int Port { get { return 22; } }
public static string Username { get { return "oleg"; } }
public static string Username { get { return "tester"; } }
public static string Password { get { return "Maya2kap#"; } }
public static string Password { get { return "tester"; } }
public static string RsaKeyFilePath { get { return @"RSA key path"; } }
@@ -0,0 +1,54 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Renci.SshClient.Common
{
public class ConnectingEventArgs : EventArgs
{
public IDictionary<string, string> KeyExchangeAlgorithms { get; private set; }
public IDictionary<string, string> Encryptions { get; private set; }
public IDictionary<string, string> HmacAlgorithms { get; private set; }
public IDictionary<string, string> HostKeyAlgorithms { get; private set; }
public IDictionary<string, string> SupportedAuthenticationMethods { get; private set; }
public IDictionary<string, string> CompressionAlgorithms { get; private set; }
public string Host { get; set; }
public int Port { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public PrivateKeyFile KeyFile { get; set; }
public TimeSpan Timeout { get; set; }
public int RetryAttempts { get; set; }
public int MaxSessions { get; set; }
public ConnectingEventArgs(
IDictionary<string, string> keyExchangeAlgorithms,
IDictionary<string, string> encryptions,
IDictionary<string, string> hmacAlgorithms,
IDictionary<string, string> hostKeyAlgorithms,
IDictionary<string, string> supportedAuthenticationMethods,
IDictionary<string, string> compressionAlgorithms)
{
this.KeyExchangeAlgorithms = keyExchangeAlgorithms;
this.Encryptions = encryptions;
this.HmacAlgorithms = hmacAlgorithms;
this.HostKeyAlgorithms = hostKeyAlgorithms;
this.SupportedAuthenticationMethods = supportedAuthenticationMethods;
this.CompressionAlgorithms = compressionAlgorithms;
}
}
}
@@ -64,6 +64,7 @@
<Compile Include="Common\ChannelEventArgs.cs" />
<Compile Include="Common\ChannelOpenFailedEventArgs.cs" />
<Compile Include="Common\ChannelRequestEventArgs.cs" />
<Compile Include="Common\ConnectingEventArgs.cs" />
<Compile Include="Common\SshConnectionException.cs" />
<Compile Include="Common\SshOperationTimeoutException.cs" />
<Compile Include="Messages\Connection\ChannelOpen\ChannelOpenInfo.cs" />
+34 -10
View File
@@ -220,7 +220,7 @@ namespace Renci.SshClient
public event EventHandler<ErrorEventArgs> ErrorOccured;
public event EventHandler<EventArgs> Connecting;
public event EventHandler<ConnectingEventArgs> Connecting;
public event EventHandler<EventArgs> Connected;
@@ -450,25 +450,49 @@ namespace Renci.SshClient
if (this.IsConnected)
return;
if (this.Connecting != null)
{
// TODO: Create custom ConnectingEventArgs to allow to pass different connection parameters
this.Connecting(this, new EventArgs());
}
lock (this)
{
// If connected dont connect again
// If connected don't connect again
if (this.IsConnected)
return;
var eventArgs = new ConnectingEventArgs(this.KeyExchangeAlgorithms,
this.Encryptions,
this.HmacAlgorithms,
this.HostKeyAlgorithms,
this.SupportedAuthenticationMethods,
this.CompressionAlgorithms);
// Populate event args connection information
eventArgs.Host = this.ConnectionInfo.Host;
eventArgs.Port = this.ConnectionInfo.Port;
eventArgs.Username = this.ConnectionInfo.Username;
eventArgs.Password = this.ConnectionInfo.Password;
eventArgs.KeyFile = this.ConnectionInfo.KeyFile;
eventArgs.Timeout = this.ConnectionInfo.Timeout;
eventArgs.RetryAttempts = this.ConnectionInfo.RetryAttempts;
eventArgs.MaxSessions = this.ConnectionInfo.MaxSessions;
if (this.Connecting != null)
{
this.Connecting(this, eventArgs);
// Update connection information if it was changed by event handler
this.ConnectionInfo.Host = eventArgs.Host;
this.ConnectionInfo.Port = eventArgs.Port;
this.ConnectionInfo.Username = eventArgs.Username;
this.ConnectionInfo.Password = eventArgs.Password;
this.ConnectionInfo.KeyFile = eventArgs.KeyFile;
this.ConnectionInfo.Timeout = eventArgs.Timeout;
this.ConnectionInfo.RetryAttempts = eventArgs.RetryAttempts;
}
var ep = new IPEndPoint(Dns.GetHostAddresses(this.ConnectionInfo.Host)[0], this.ConnectionInfo.Port);
this._socket = new Socket(ep.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
// Connect socket with 5 seconds timeout
var connectResult = this._socket.BeginConnect(ep, null, null);
connectResult.AsyncWaitHandle.WaitOne(this.ConnectionInfo.Timeout);
connectResult.AsyncWaitHandle.WaitOne(eventArgs.Timeout);
this._socket.EndConnect(connectResult);
@@ -554,7 +578,7 @@ namespace Renci.SshClient
foreach (var methodName in this.SupportedAuthenticationMethods.Keys)
{
var userAuthentication = this.SupportedAuthenticationMethods[methodName].CreateInstance<UserAuthentication>();
userAuthentication.Init(this);
if (userAuthentication.Execute())
@@ -5,6 +5,7 @@ using System.Text;
using System.IO;
using Renci.SshClient.Sftp;
using Renci.SshClient.Security;
using Renci.SshClient.Common;
namespace Renci.SshClient
{
@@ -37,6 +38,11 @@ namespace Renci.SshClient
}
}
/// <summary>
/// Occurs when client is about to connect to the server.
/// </summary>
public event EventHandler<ConnectingEventArgs> Connecting;
/// <summary>
/// Initializes a new instance of the <see cref="SshBaseClient"/> class.
/// </summary>
@@ -60,6 +66,7 @@ namespace Renci.SshClient
}
this.Session = new Session(this.ConnectionInfo);
this.Session.Connecting += Session_Connecting;
this.Session.Connect();
this.OnConnected();
@@ -73,6 +80,7 @@ namespace Renci.SshClient
this.OnDisconnecting();
this.Session.Disconnect();
this.Session.Connecting -= Session_Connecting;
this.OnDisconnected();
}
@@ -117,6 +125,15 @@ namespace Renci.SshClient
}
private void Session_Connecting(object sender, ConnectingEventArgs e)
{
if (this.Connecting != null)
{
this.Connecting(this, e);
}
}
#region IDisposable Members
private bool _isDisposed = false;
@@ -8,6 +8,7 @@ using Renci.SshClient.Common;
using Renci.SshClient.Messages;
using Renci.SshClient.Messages.Connection;
using Renci.SshClient.Messages.Transport;
using System.Threading.Tasks;
namespace Renci.SshClient
{
@@ -203,8 +204,8 @@ namespace Renci.SshClient
this._asyncResult.IsCompleted = true;
if (this._callback != null)
{
// TODO: Execute this method on different thread since it will be run on message listener
this._callback(this._asyncResult);
// Execute callback on different thread
Task.Factory.StartNew(() => { this._callback(this._asyncResult); });
}
((EventWaitHandle)_asyncResult.AsyncWaitHandle).Set();
}