/*
* Copyright (C) 2004-2005 Jonathan Bindel
* Copyright (C) 2006-2007 Eskil Bylund
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
using System;
using System.Net;
using DCSharp.Backend.Managers;
using DCSharp.Backend.Objects;
using DCSharp.Backend.Protocols;
using DCSharp.Extras;
using DCSharp.Logging;
namespace DCSharp.Backend.Connections{
public class MessageEventArgs : EventArgs
{
public MessageEventArgs(Identity from, Identity to, string message)
{
this.message = message;
this.from = from;
this.to = to;
}
public string Message
{
get { return message; }
}
private string message;
public Identity From
{
get { return from; }
}
private Identity from;
public Identity To
{
get { return to; }
}
private Identity to;
}
public class HubConnection : Connection
{
public event EventHandler NameChanged;
public event EventHandler<MessageEventArgs> Message;
public event EventHandler<MessageEventArgs> PrivateMessage;
private static Logger log = LogManager.GetLogger("HubConnection");
#region Constructors
public HubConnection(string hostname, LocalIdentity localIdentity,
IHubProtocol protocol) : base((IProtocol)protocol)
{
if (hostname == null)
{
throw new ArgumentNullException("hostname");
}
if (localIdentity == null)
{
throw new ArgumentNullException("localIdentity");
}
this.hostname = hostname;
this.localIdentity = localIdentity;
users = new UserManager();
}
#endregion
#region Properties
/// <summary>
/// Gets the local identity for this hub.
/// </summary>
/// <value>The local identity for this hub.</value>
public LocalIdentity LocalIdentity
{
get { return localIdentity; }
}
private LocalIdentity localIdentity;
/// <summary>
/// Gets or set the password for this hub.
/// </summary>
/// <value>The password for this hub.</value>
public string Password
{
get { return password; }
set { password = value; }
}
private string password;
/// <summary>
/// Gets or set the name of the hub.
/// </summary>
/// <value>The name of the hub.</value>
public string Name
{
get { return name; }
set {
name = value;
OnNameChanged();
}
}
private string name;
/// <summary>
/// Gets the address to the hub.
/// </summary>
/// <value>The address to the hub.</value>
/// <remarks>The address is only available after connecting to the hub.</remarks>
public string Address
{
get { return address; }
}
private string address;
/// <summary>
/// Gets or set the hub hostname.
/// </summary>
/// <value>The hub hostname.</value>
public string Hostname
{
get { return hostname; }
}
internal string hostname;
public UserManager Users
{
get { return users; }
}
private UserManager users;
protected IHubProtocol HubProtocol
{
get { return (IHubProtocol)Protocol; }
}
#endregion
#region Methods
#region Connect
public override void Connect()
{
State = ConnectionState.Connecting;
string address = Util.AddressPart(hostname);
try
{
Dns.BeginGetHostEntry(address, new AsyncCallback(HostEntryReceived),
null);
}
catch (Exception e)
{
OnError(ConnectionError.Dns, e);
Disconnect();
}
}
private void HostEntryReceived(IAsyncResult ar)
{
IPHostEntry ipHostEntry;
try
{
ipHostEntry = Dns.EndGetHostEntry(ar);
IPAddress ip = ipHostEntry.AddressList[0];
int port = Util.PortPart(hostname);
if (port < IPEndPoint.MinPort || port > IPEndPoint.MaxPort)
{
port = 411;
}
EndPoint = new IPEndPoint(ip, port);
this.address = EndPoint.ToString();
}
catch (Exception e)
{
OnError(ConnectionError.Dns, e);
Disconnect();
return;
}
base.Connect();
}
#endregion
#region Send/Receive
internal override void Send(string message, System.Text.Encoding encoding)
{
base.Send(message, encoding);
log.Debug("Sent: " + message, null, this);
}
internal override void ConnectionSend(string message)
{
base.ConnectionSend(message);
log.Debug("Sent: " + message, null, this);
}
protected override void HandleMessage(string message)
{
log.Debug("Received: " + message, null, this);
base.HandleMessage(message);
}
#endregion
public void RequestConnection(Identity user)
{
if (user == null)
{
throw new ArgumentNullException("user");
}
this.HubProtocol.RequestConnection(user);
}
public void Search(SearchInfo searchInfo)
{
if (searchInfo == null)
{
throw new ArgumentNullException("searchInfo");
}
this.HubProtocol.Search(searchInfo);
}
public void SendMessage(string message)
{
if (message == null)
{
throw new ArgumentNullException("message");
}
this.HubProtocol.SendMessage(message);
}
public void SendPrivateMessage(Identity user, string message)
{
if (user == null)
{
throw new ArgumentNullException("user");
}
if (message == null)
{
throw new ArgumentNullException("message");
}
this.HubProtocol.SendPrivateMessage(user, message);
}
public bool Equals(HubConnection hub)
{
if (this == hub ||
this.Hostname == hub.Hostname ||
(this.Address != null && this.Address == hub.Address))
{
return true;
}
return false;
}
public override string ToString()
{
return hostname;
}
protected override void OnError(ConnectionError error, Exception e)
{
log.Error(error.ToString(), e, this);
base.OnError(error, e);
}
protected override void OnStateChanged()
{
log.Info(State.ToString(), null, this);
base.OnStateChanged();
}
protected virtual void OnNameChanged()
{
if (NameChanged != null)
{
NameChanged(this, EventArgs.Empty);
}
}
protected virtual void OnMessage(Identity from, string message)
{
if (Message != null)
{
Message(this, new MessageEventArgs(from, null, message));
}
}
protected virtual void OnPrivateMessage(Identity from, Identity to,
string message)
{
if (PrivateMessage != null)
{
PrivateMessage(this, new MessageEventArgs(from, to, message));
}
}
internal void EmitMessage(Identity from, string message)
{
OnMessage(from, message);
}
internal void EmitPrivateMessage(Identity from, Identity to,
string message)
{
OnPrivateMessage(from, to, message);
}
#region IDisposable Members
protected override void Dispose(bool disposing)
{
users.Clear();
base.Dispose(disposing);
}
#endregion
#endregion
}
}
|