Refactor channel message handling by converting into events

This commit is contained in:
olegkap_cp
2010-11-05 20:42:49 +00:00
parent ba9208e33e
commit a322c96a1c
13 changed files with 342 additions and 188 deletions
@@ -100,24 +100,18 @@ namespace Renci.SshClient.Tests
[TestMethod]
public void TestMultipleThreadMultipleSessions_10000()
{
// TODO: Restore test to 10000 items
var s = CreateShellUsingPassword();
s.Connect();
var numOfLoops = 100000;
var exeCounter = 0;
System.Threading.Tasks.Parallel.For(0, numOfLoops,
System.Threading.Tasks.Parallel.For(0, 10000,
(counter) =>
{
var result = ExecuteTestCommand(s);
Debug.WriteLine(string.Format("TestMultipleThreadMultipleConnections #{0}", counter));
exeCounter++;
Assert.IsTrue(result);
}
);
s.Disconnect();
Assert.AreEqual(exeCounter, numOfLoops);
}
[TestMethod]
@@ -125,8 +119,7 @@ namespace Renci.SshClient.Tests
{
try
{
// TODO: Restore test to 10000 items
System.Threading.Tasks.Parallel.For(0, 100,
System.Threading.Tasks.Parallel.For(0, 10000,
() =>
{
var s = CreateShellUsingPassword();
@@ -1,11 +0,0 @@
using System;
using Renci.SshClient.Messages.Connection;
namespace Renci.SshClient
{
internal class ChannelOpeningEventArgs : EventArgs
{
public ChannelOpenMessage Message { get; set; }
}
}
@@ -62,6 +62,18 @@ namespace Renci.SshClient.Channels
this.Session.RegisterMessageType<ChannelEofMessage>(MessageTypes.ChannelEof);
this.Session.RegisterMessageType<ChannelCloseMessage>(MessageTypes.ChannelClose);
this.Session.ChannelOpen += OnChannelOpen;
this.Session.ChannelOpenConfirmation += OnChannelOpenConfirmation;
this.Session.ChannelOpenFailure += OnChannelOpenFailure;
this.Session.ChannelWindowAdjust += OnChannelWindowAdjust;
this.Session.ChannelData += OnChannelData;
this.Session.ChannelExtendedData += OnChannelExtendedData;
this.Session.ChannelEof += OnChannelEof;
this.Session.ChannelClose += OnChannelClose;
this.Session.ChannelRequest += OnChannelRequest;
this.Session.ChannelSuccess += OnChannelSuccess;
this.Session.ChannelFailure += OnChannelFailure;
}
public virtual void Close()
@@ -77,42 +89,65 @@ namespace Renci.SshClient.Channels
this.CloseCleanup();
}
internal void HandleChannelMessage(ChannelMessage message)
{
this.HandleMessage((dynamic)message);
}
#region Channel virtual methods
protected virtual void OnChannelData(string data)
protected virtual void OnOpen(ChannelTypes channelTypes, uint initialWindowSize, uint maximumPacketSize, string connectedAddress, uint connectedPort, string originatorAddress, uint originatorPort)
{
}
protected virtual void OnChannelExtendedData(string data, uint dataTypeCode)
protected virtual void OnOpenConfirmation(uint remoteChannelNumber, uint initialWindowSize, uint maximumPacketSize)
{
this.RemoteChannelNumber = remoteChannelNumber;
this.ServerWindowSize = initialWindowSize;
this.PacketSize = maximumPacketSize;
this.IsOpen = true;
}
protected virtual void OnOpenFailure(uint reasonCode, string description, string language)
{
}
protected virtual void OnChannelSuccess()
protected virtual void OnWindowAdjust(uint bytesToAdd)
{
this.ServerWindowSize += bytesToAdd;
this._channelWindowAdjustWaitHandle.Set();
}
protected virtual void OnData(string data)
{
this.AdjustDataWindow(data);
}
protected virtual void OnExtendedData(string data, uint dataTypeCode)
{
this.AdjustDataWindow(data);
}
protected virtual void OnEof()
{
}
protected virtual void OnChannelEof()
protected virtual void OnClose()
{
this.CloseCleanup();
this._channelClosedWaitHandle.Set();
}
protected virtual void OnRequest(ChannelRequestNames requestName, bool wantReply, string command, string subsystemName, uint exitStatus)
{
}
protected virtual void OnChannelOpen()
protected virtual void OnSuccess()
{
}
protected virtual void OnChannelClose()
protected virtual void OnFailure()
{
}
protected virtual void OnChannelRequest(ChannelRequestMessage message)
{
}
protected virtual void OnChannelFailed(uint reasonCode, string description)
{
}
#endregion
protected void SendMessage(Message message)
{
@@ -143,69 +178,109 @@ namespace Renci.SshClient.Channels
this.Session.SendMessage(message);
}
#region Message handlers
private void HandleMessage<T>(T message) where T : Message
protected void CloseCleanup()
{
throw new NotSupportedException(string.Format("Message type '{0}' is not supported.", message.MessageType));
if (!this.IsOpen)
return;
this.IsOpen = false;
this.SendChannelCloseMessage();
}
private void HandleMessage(ChannelOpenConfirmationMessage message)
#region Channel message event handlers
private void OnChannelOpen(object sender, MessageEventArgs<ChannelOpenMessage> e)
{
this.RemoteChannelNumber = message.RemoteChannelNumber;
this.ServerWindowSize = message.InitialWindowSize;
this.PacketSize = message.MaximumPacketSize;
this.IsOpen = true;
this.OnChannelOpen();
if (e.Message.LocalChannelNumber == this.LocalChannelNumber)
{
this.OnOpen(e.Message.ChannelType, e.Message.InitialWindowSize, e.Message.MaximumPacketSize, e.Message.ConnectedAddress, e.Message.ConnectedPort, e.Message.OriginatorAddress, e.Message.OriginatorPort);
}
}
private void HandleMessage(ChannelOpenFailureMessage message)
private void OnChannelOpenConfirmation(object sender, MessageEventArgs<ChannelOpenConfirmationMessage> e)
{
this.OnChannelFailed(message.ReasonCode, message.Description);
if (e.Message.LocalChannelNumber == this.LocalChannelNumber)
{
this.OnOpenConfirmation(e.Message.RemoteChannelNumber, e.Message.InitialWindowSize, e.Message.MaximumPacketSize);
}
}
private void HandleMessage(ChannelWindowAdjustMessage message)
private void OnChannelOpenFailure(object sender, MessageEventArgs<ChannelOpenFailureMessage> e)
{
this.ServerWindowSize += message.BytesToAdd;
this._channelWindowAdjustWaitHandle.Set();
if (e.Message.LocalChannelNumber == this.LocalChannelNumber)
{
this.OnOpenFailure(e.Message.ReasonCode, e.Message.Description, e.Message.Language);
}
}
private void HandleMessage(ChannelDataMessage message)
private void OnChannelWindowAdjust(object sender, MessageEventArgs<ChannelWindowAdjustMessage> e)
{
this.AdjustDataWindow(message.Data);
this.OnChannelData(message.Data);
if (e.Message.LocalChannelNumber == this.LocalChannelNumber)
{
this.OnWindowAdjust(e.Message.BytesToAdd);
}
}
private void HandleMessage(ChannelExtendedDataMessage message)
private void OnChannelData(object sender, MessageEventArgs<ChannelDataMessage> e)
{
this.AdjustDataWindow(message.Data);
this.OnChannelExtendedData(message.Data, message.DataTypeCode);
if (e.Message.LocalChannelNumber == this.LocalChannelNumber)
{
this.OnData(e.Message.Data);
}
}
private void HandleMessage(ChannelRequestMessage message)
private void OnChannelExtendedData(object sender, MessageEventArgs<ChannelExtendedDataMessage> e)
{
this.OnChannelRequest(message);
if (e.Message.LocalChannelNumber == this.LocalChannelNumber)
{
this.OnExtendedData(e.Message.Data, e.Message.DataTypeCode);
}
}
private void HandleMessage(ChannelSuccessMessage message)
private void OnChannelEof(object sender, MessageEventArgs<ChannelEofMessage> e)
{
this.OnChannelSuccess();
if (e.Message.LocalChannelNumber == this.LocalChannelNumber)
{
this.OnEof();
}
}
private void HandleMessage(ChannelEofMessage message)
private void OnChannelClose(object sender, MessageEventArgs<ChannelCloseMessage> e)
{
this.OnChannelEof();
if (e.Message.LocalChannelNumber == this.LocalChannelNumber)
{
this.OnClose();
//// TODO: Refactor so this could will not be here
//this.CloseCleanup();
//this._channelClosedWaitHandle.Set();
}
}
private void HandleMessage(ChannelCloseMessage message)
private void OnChannelRequest(object sender, MessageEventArgs<ChannelRequestMessage> e)
{
this.OnChannelClose();
if (e.Message.LocalChannelNumber == this.LocalChannelNumber)
{
this.OnRequest(e.Message.RequestName, e.Message.WantReply, e.Message.Command, e.Message.SubsystemName, e.Message.ExitStatus);
}
}
this.CloseCleanup();
private void OnChannelSuccess(object sender, MessageEventArgs<ChannelSuccessMessage> e)
{
if (e.Message.LocalChannelNumber == this.LocalChannelNumber)
{
this.OnSuccess();
}
}
this._channelClosedWaitHandle.Set();
private void OnChannelFailure(object sender, MessageEventArgs<ChannelFailureMessage> e)
{
if (e.Message.LocalChannelNumber == this.LocalChannelNumber)
{
this.OnFailure();
}
}
#endregion
@@ -244,15 +319,6 @@ namespace Renci.SshClient.Channels
}
}
protected void CloseCleanup()
{
if (!this.IsOpen)
return;
this.IsOpen = false;
this.SendChannelCloseMessage();
}
#region IDisposable Members
protected abstract void OnDisposing();
@@ -120,32 +120,27 @@ namespace Renci.SshClient.Channels
readerTask.Wait();
}
protected override void OnChannelData(string data)
protected override void OnData(string data)
{
base.OnChannelData(data);
base.OnData(data);
this._socket.Send(data.GetSshBytes().ToArray(), 0, data.Length, SocketFlags.None);
}
protected override void OnChannelOpen()
protected override void OnOpenConfirmation(uint remoteChannelNumber, uint initialWindowSize, uint maximumPacketSize)
{
base.OnChannelOpen();
base.OnOpenConfirmation(remoteChannelNumber, initialWindowSize, maximumPacketSize);
this._channelOpen.Set();
}
protected override void OnChannelEof()
protected override void OnEof()
{
base.OnChannelEof();
base.OnEof();
this._channelEof.Set();
}
protected override void OnChannelClose()
{
base.OnChannelClose();
}
protected override void OnDisposing()
{
@@ -89,9 +89,9 @@ namespace Renci.SshClient.Channels
this.Close();
}
protected override void OnChannelData(string data)
protected override void OnData(string data)
{
base.OnChannelData(data);
base.OnData(data);
// Read data from the channel and send it to the port
this._socket.Send(data.GetSshBytes().ToArray());
@@ -57,16 +57,16 @@ namespace Renci.SshClient.Channels
}
}
protected override void OnChannelOpen()
protected override void OnOpenConfirmation(uint remoteChannelNumber, uint initialWindowSize, uint maximumPacketSize)
{
base.OnChannelOpen();
base.OnOpenConfirmation(remoteChannelNumber, initialWindowSize, maximumPacketSize);
this._channelOpenResponseWaitHandle.Set();
}
protected override void OnChannelClose()
protected override void OnClose()
{
base.OnChannelClose();
base.OnClose();
// Throw an error if exit status is not 0
if (this.ExitStatus > 0)
@@ -81,9 +81,9 @@ namespace Renci.SshClient.Channels
}
}
protected override void OnChannelExtendedData(string data, uint dataTypeCode)
protected override void OnExtendedData(string data, uint dataTypeCode)
{
base.OnChannelExtendedData(data, dataTypeCode);
base.OnExtendedData(data, dataTypeCode);
if (dataTypeCode == 1)
{
@@ -93,7 +93,7 @@ namespace Renci.SshClient.Channels
}
}
protected override void OnChannelFailed(uint reasonCode, string description)
protected override void OnOpenFailure(uint reasonCode, string description, string language)
{
// TODO: See why occasionaly open channel will fail when try to utilze maximum number of channels
@@ -108,34 +108,34 @@ namespace Renci.SshClient.Channels
this._channelOpenResponseWaitHandle.Set();
}
protected override void OnChannelRequest(ChannelRequestMessage message)
protected override void OnRequest(ChannelRequestNames requestName, bool wantReply, string command, string subsystemName, uint exitStatus)
{
base.OnChannelRequest(message);
base.OnRequest(requestName, wantReply, command, subsystemName, exitStatus);
Message replyMessage = new ChannelFailureMessage()
{
LocalChannelNumber = message.LocalChannelNumber,
LocalChannelNumber = this.LocalChannelNumber,
};
if (message.RequestName == ChannelRequestNames.ExitStatus)
if (requestName == ChannelRequestNames.ExitStatus)
{
this.ExitStatus = message.ExitStatus;
this.ExitStatus = exitStatus;
replyMessage = new ChannelSuccessMessage()
{
LocalChannelNumber = message.LocalChannelNumber,
LocalChannelNumber = this.LocalChannelNumber,
};
}
else if (message.RequestName == ChannelRequestNames.PseudoTerminal)
else if (requestName == ChannelRequestNames.PseudoTerminal)
{
// TODO: Check if when this request is received what to do, I suspect we receive this request when no more channel sessions are available
}
else
{
throw new NotImplementedException(string.Format("Request name {0} is not implemented.", message.RequestName));
throw new NotImplementedException(string.Format("Request name {0} is not implemented.", requestName));
}
if (message.WantReply)
if (wantReply)
{
this.SendMessage(replyMessage);
}
@@ -86,23 +86,23 @@ namespace Renci.SshClient.Channels
}
}
protected override void OnChannelEof()
protected override void OnEof()
{
base.OnChannelEof();
base.OnEof();
//this.ExecutionCompleted();
}
protected override void OnClose()
{
base.OnClose();
this.ExecutionCompleted();
}
protected override void OnChannelClose()
protected override void OnData(string data)
{
base.OnChannelClose();
this.ExecutionCompleted();
}
protected override void OnChannelData(string data)
{
base.OnChannelData(data);
base.OnData(data);
if (this._channelData != null)
{
@@ -118,9 +118,9 @@ namespace Renci.SshClient.Channels
}
}
protected override void OnChannelExtendedData(string data, uint dataTypeCode)
protected override void OnExtendedData(string data, uint dataTypeCode)
{
base.OnChannelExtendedData(data, dataTypeCode);
base.OnExtendedData(data, dataTypeCode);
// TODO: dataTypeCode curently ignored
if (this._channelExtendedData != null)
@@ -144,6 +144,7 @@ namespace Renci.SshClient.Channels
this._channelExtendedData.Flush();
}
// TODO: Execute this method on different thread since it will be run on message listener
this._asyncResult.IsCompleted = true;
if (this._callback != null)
{
@@ -205,17 +205,17 @@ namespace Renci.SshClient.Channels
}
protected override void OnChannelSuccess()
protected override void OnSuccess()
{
base.OnChannelSuccess();
base.OnSuccess();
this._channelRequestSuccessWaitHandle.Set();
}
protected override void OnChannelData(string data)
protected override void OnData(string data)
{
base.OnChannelData(data);
base.OnData(data);
if (this._packetData == null)
{
@@ -22,7 +22,7 @@ namespace Renci.SshClient
this.Session.RequestSuccess += Session_RequestSuccess;
this.Session.RequestFailure += Session_RequestFailure;
this.Session.ChannelOpening += Session_ChannelOpening;
this.Session.ChannelOpen += Session_ChannelOpening;
// Send global request to start direct tcpip
this.Session.SendMessage(new GlobalRequestMessage
@@ -38,7 +38,7 @@ namespace Renci.SshClient
if (!this._requestStatus)
{
// If request failed dont handle channel opening for this request
this.Session.ChannelOpening -= Session_ChannelOpening;
this.Session.ChannelOpen -= Session_ChannelOpening;
}
}
@@ -57,10 +57,10 @@ namespace Renci.SshClient
this.Session.RequestSuccess -= Session_RequestSuccess;
this.Session.RequestFailure -= Session_RequestFailure;
this.Session.ChannelOpening -= Session_ChannelOpening;
this.Session.ChannelOpen -= Session_ChannelOpening;
}
private void Session_ChannelOpening(object sender, ChannelOpeningEventArgs e)
private void Session_ChannelOpening(object sender, MessageEventArgs<ChannelOpenMessage> e)
{
// Ensure that this is corresponding request
if (e.Message.ConnectedAddress == this.ConnectedHost && e.Message.ConnectedPort == this.BoundPort)
@@ -86,12 +86,12 @@ namespace Renci.SshClient
this._globalRequestResponse.Set();
}
private void Session_RequestSuccess(object sender, RequestSuccessEventArgs e)
private void Session_RequestSuccess(object sender, MessageEventArgs<RequestSuccessMessage> e)
{
this._requestStatus = true;
if (this.BoundPort == 0)
{
this.BoundPort = e.BoundPort;
this.BoundPort = (e.Message.BoundPort == null) ? 0 : e.Message.BoundPort.Value;
}
this._globalRequestResponse.Set();
@@ -0,0 +1,14 @@
using System;
namespace Renci.SshClient
{
internal class MessageEventArgs<T> : EventArgs
{
public T Message { get; private set; }
public MessageEventArgs(T message)
{
this.Message = message;
}
}
}
@@ -60,7 +60,7 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="ChannelOpeningEventArgs.cs" />
<Compile Include="MessageEventArgs.cs" />
<Compile Include="Channels\ChannelAsyncResult.cs" />
<Compile Include="Channels\ChannelEventArgs.cs" />
<Compile Include="Channels\ChannelDirectTcpip.cs" />
@@ -73,7 +73,6 @@
<Compile Include="ForwardedPortRemote.cs" />
<Compile Include="Messages\Connection\ChannelOpenDirectTcpIPMessage.cs" />
<Compile Include="Messages\Connection\GlobalRequestNames.cs" />
<Compile Include="RequestSuccessEventArgs.cs" />
<Compile Include="Security\Algorithm.cs" />
<Compile Include="Security\Cipher.cs" />
<Compile Include="Security\CipherAES.cs" />
@@ -1,9 +0,0 @@
using System;
namespace Renci.SshClient
{
internal class RequestSuccessEventArgs : EventArgs
{
public uint BoundPort { get; set; }
}
}
+152 -46
View File
@@ -198,11 +198,79 @@ namespace Renci.SshClient
/// <value>The connection info.</value>
public ConnectionInfo ConnectionInfo { get; private set; }
public event EventHandler<ChannelOpeningEventArgs> ChannelOpening;
#region Message events
public event EventHandler<RequestSuccessEventArgs> RequestSuccess;
/// <summary>
/// Occurs when <see cref="GlobalRequestMessage"/> message received
/// </summary>
public event EventHandler<MessageEventArgs<GlobalRequestMessage>> GlobalRequest;
public event EventHandler RequestFailure;
/// <summary>
/// Occurs when <see cref="RequestSuccessMessage"/> message received
/// </summary>
public event EventHandler<MessageEventArgs<RequestSuccessMessage>> RequestSuccess;
/// <summary>
/// Occurs when <see cref="RequestFailureMessage"/> message received
/// </summary>
public event EventHandler<MessageEventArgs<RequestFailureMessage>> RequestFailure;
/// <summary>
/// Occurs when <see cref="ChannelOpenMessage"/> message received
/// </summary>
public event EventHandler<MessageEventArgs<ChannelOpenMessage>> ChannelOpen;
/// <summary>
/// Occurs when <see cref="ChannelOpenConfirmationMessage"/> message received
/// </summary>
public event EventHandler<MessageEventArgs<ChannelOpenConfirmationMessage>> ChannelOpenConfirmation;
/// <summary>
/// Occurs when <see cref="ChannelOpenFailureMessage"/> message received
/// </summary>
public event EventHandler<MessageEventArgs<ChannelOpenFailureMessage>> ChannelOpenFailure;
/// <summary>
/// Occurs when <see cref="ChannelWindowAdjustMessage"/> message received
/// </summary>
public event EventHandler<MessageEventArgs<ChannelWindowAdjustMessage>> ChannelWindowAdjust;
/// <summary>
/// Occurs when <see cref="ChannelDataMessage"/> message received
/// </summary>
public event EventHandler<MessageEventArgs<ChannelDataMessage>> ChannelData;
/// <summary>
/// Occurs when <see cref="ChannelExtendedDataMessage"/> message received
/// </summary>
public event EventHandler<MessageEventArgs<ChannelExtendedDataMessage>> ChannelExtendedData;
/// <summary>
/// Occurs when <see cref="ChannelEofMessage"/> message received
/// </summary>
public event EventHandler<MessageEventArgs<ChannelEofMessage>> ChannelEof;
/// <summary>
/// Occurs when <see cref="ChannelCloseMessage"/> message received
/// </summary>
public event EventHandler<MessageEventArgs<ChannelCloseMessage>> ChannelClose;
/// <summary>
/// Occurs when <see cref="ChannelRequestMessage"/> message received
/// </summary>
public event EventHandler<MessageEventArgs<ChannelRequestMessage>> ChannelRequest;
/// <summary>
/// Occurs when <see cref="ChannelSuccessMessage"/> message received
/// </summary>
public event EventHandler<MessageEventArgs<ChannelSuccessMessage>> ChannelSuccess;
/// <summary>
/// Occurs when <see cref="ChannelFailureMessage"/> message received
/// </summary>
public event EventHandler<MessageEventArgs<ChannelFailureMessage>> ChannelFailure;
#endregion
/// <summary>
/// Initializes a new instance of the <see cref="Session"/> class.
@@ -401,16 +469,6 @@ namespace Renci.SshClient
lock (this)
{
channel.Initialize(this, serverChannelNumber, windowSize, packetSize);
try
{
this._sessionChannels.Add(channel.LocalChannelNumber, channel);
}
catch (Exception exp)
{
throw;
}
}
return channel;
}
@@ -623,10 +681,10 @@ namespace Renci.SshClient
protected void HandleMessage<T>(T message) where T : Message
{
// Do nothing as message could be proccessed by other module
if (message is ChannelMessage)
{
this.HandleMessage(message as ChannelMessage);
}
//if (message is ChannelMessage)
//{
// this.HandleMessage(message as ChannelMessage);
//}
}
#region Handle transport messages
@@ -675,18 +733,17 @@ namespace Renci.SshClient
protected virtual void HandleMessage(GlobalRequestMessage message)
{
// TODO: Add implemention for this message
if (this.GlobalRequest != null)
{
this.GlobalRequest(this, new MessageEventArgs<GlobalRequestMessage>(message));
}
}
protected virtual void HandleMessage(RequestSuccessMessage message)
{
// TODO: Add implemention for this message
if (this.RequestSuccess != null)
{
this.RequestSuccess(this, new RequestSuccessEventArgs
{
BoundPort = (message.BoundPort == null) ? 0 : message.BoundPort.Value,
});
this.RequestSuccess(this, new MessageEventArgs<RequestSuccessMessage>(message));
}
}
@@ -694,54 +751,99 @@ namespace Renci.SshClient
{
if (this.RequestFailure != null)
{
this.RequestFailure(this, new EventArgs());
this.RequestFailure(this, new MessageEventArgs<RequestFailureMessage>(message));
}
}
#endregion
#region Handle channel messages
#region Handle channel messages and raise channel events
protected void HandleMessage(ChannelOpenMessage message)
{
if (this.ChannelOpening != null)
if (this.ChannelOpen != null)
{
this.ChannelOpening(this, new ChannelOpeningEventArgs
{
Message = message,
});
this.ChannelOpen(this, new MessageEventArgs<ChannelOpenMessage>(message));
}
}
protected void HandleMessage(ChannelMessage message)
{
// TODO: Improve session channel managment, sometimes it sends a message that is not in sessionChannels collection
this._sessionChannels[message.LocalChannelNumber].HandleChannelMessage(message);
}
protected void HandleMessage(ChannelOpenConfirmationMessage message)
{
this.HandleMessage((ChannelMessage)message);
if (this.ChannelOpenConfirmation != null)
{
this.ChannelOpenConfirmation(this, new MessageEventArgs<ChannelOpenConfirmationMessage>(message));
}
}
protected void HandleMessage(ChannelOpenFailureMessage message)
{
if (this.ChannelOpenFailure != null)
{
this.ChannelOpenFailure(this, new MessageEventArgs<ChannelOpenFailureMessage>(message));
}
}
protected void HandleMessage(ChannelWindowAdjustMessage message)
{
if (this.ChannelWindowAdjust != null)
{
this.ChannelWindowAdjust(this, new MessageEventArgs<ChannelWindowAdjustMessage>(message));
}
}
protected void HandleMessage(ChannelDataMessage message)
{
if (this.ChannelData != null)
{
this.ChannelData(this, new MessageEventArgs<ChannelDataMessage>(message));
}
}
protected void HandleMessage(ChannelExtendedDataMessage message)
{
if (this.ChannelExtendedData != null)
{
this.ChannelExtendedData(this, new MessageEventArgs<ChannelExtendedDataMessage>(message));
}
}
protected void HandleMessage(ChannelEofMessage message)
{
if (this.ChannelEof != null)
{
this.ChannelEof(this, new MessageEventArgs<ChannelEofMessage>(message));
}
}
protected void HandleMessage(ChannelCloseMessage message)
{
this.HandleMessage((ChannelMessage)message);
lock (this._sessionChannels)
if (this.ChannelClose != null)
{
this._sessionChannels.Remove(message.LocalChannelNumber);
this.ChannelClose(this, new MessageEventArgs<ChannelCloseMessage>(message));
}
}
protected void HandleMessage(ChannelRequestMessage message)
{
if (this.ChannelRequest != null)
{
this.ChannelRequest(this, new MessageEventArgs<ChannelRequestMessage>(message));
}
}
protected void HandleMessage(ChannelSuccessMessage message)
{
if (this.ChannelSuccess != null)
{
this.ChannelSuccess(this, new MessageEventArgs<ChannelSuccessMessage>(message));
}
}
protected void HandleMessage(ChannelFailureMessage message)
{
this.HandleMessage((ChannelMessage)message);
lock (this._sessionChannels)
if (this.ChannelFailure != null)
{
this._sessionChannels.Remove(message.LocalChannelNumber);
this.ChannelFailure(this, new MessageEventArgs<ChannelFailureMessage>(message));
}
}
@@ -974,11 +1076,15 @@ namespace Renci.SshClient
}
else
{
// TODO: Handle each message on induvidual thread
//Task.Factory.StartNew(() =>
//{
// Handle message
this.HandleMessage((dynamic)message);
// Raise an event that message received
this.RaiseMessageReceived(this, new MessageReceivedEventArgs(message));
//});
}
}
catch (SshException exp)