using System;
using System.Collections.Generic;
using System.Text;
using Taobao.Top.Link.Channel;
namespace Taobao.Top.Link.Endpoints
{
/// logic endpoint local proxy object
///
public class EndpointProxy
{
private IList _senders;
private Random _random;
private EndpointHandler _handler;
/// get id
///
public Identity Identity { get; internal set; }
/// known by both side, like a sessionId
///
public string Token { get; internal set; }
public EndpointProxy(EndpointHandler handler)
{
this._senders = new List();
this._random = new Random();
this._handler = handler;
}
internal void Add(IChannelSender sender)
{
if (!this._senders.Contains(sender))
lock (this._senders)
if (!this._senders.Contains(sender))
this._senders.Add(sender);
}
internal void Remove(IChannelSender sender)
{
lock (this._senders)
this._senders.Remove(sender);
}
internal void Remove(string uri)
{
lock (this._senders)
{
for (var i = 0; i < this._senders.Count; i++)
{
var channel = this._senders[i] as IClientChannel;
if (channel == null)
continue;
if (!channel.Uri.ToString().Equals(uri))
continue;
this._senders.Remove(channel);
i--;
}
}
}
internal void Close(string uri, string reason)
{
lock (this._senders)
{
for (var i = 0; i < this._senders.Count; i++)
{
var channel = this._senders[i] as IClientChannel;
if (channel == null)
continue;
if (!channel.Uri.ToString().Equals(uri))
continue;
channel.Close(reason);
this._senders.Remove(channel);
i--;
}
}
}
/// check is there any sender can be used to send
///
///
public bool hasValidSender()
{
foreach (IClientChannel sender in this._senders)
{
if (sender.IsConnected)
return true;
}
return false;
}
/// send message and wait reply
///
///
///
public IDictionary SendAndWait(IDictionary message)
{
return this.SendAndWait(message, Endpoint.TIMEOUT);
}
/// send message and wait reply
///
///
/// timeout in milliseconds
///
public IDictionary SendAndWait(IDictionary message, int timeout)
{
return this.SendAndWait(null, message, timeout);
}
/// send message and wait reply
///
/// use to send, must belong this proxy
///
/// timeout in milliseconds
///
internal IDictionary SendAndWait(IChannelSender sender, IDictionary message, int timeout)
{
return this._handler.SendAndWait(this,
this.GetSender(sender),
this.CreateMessage(message),
timeout);
}
/// send message
///
///
public void Send(IDictionary message)
{
this.Send(null, message);
}
/// send message
///
/// use to send, must belong this proxy
///
internal void Send(IChannelSender sender, IDictionary message)
{
this._handler.Send(this.CreateMessage(message), this.GetSender(sender));
}
private Message CreateMessage(IDictionary message)
{
Message msg = new Message();
msg.MessageType = MessageType.SEND;
msg.Content = message;
msg.Token = this.Token;
return msg;
}
private IChannelSender GetSender(IChannelSender sender)
{
if (this._senders.Count == 0)
throw new ChannelException(Text.E_NO_SENDER);
if (this._senders.Contains(sender))
return sender;
return this._senders[this._random.Next(this._senders.Count)];
}
}
}