using System;
|
using System.Collections.Generic;
|
using System.Text;
|
using Taobao.Top.Link.Channel;
|
|
namespace Taobao.Top.Link.Endpoints
|
{
|
/// <summary>logic endpoint local proxy object
|
/// </summary>
|
public class EndpointProxy
|
{
|
private IList<IChannelSender> _senders;
|
private Random _random;
|
private EndpointHandler _handler;
|
|
/// <summary>get id
|
/// </summary>
|
public Identity Identity { get; internal set; }
|
/// <summary>known by both side, like a sessionId
|
/// </summary>
|
public string Token { get; internal set; }
|
|
public EndpointProxy(EndpointHandler handler)
|
{
|
this._senders = new List<IChannelSender>();
|
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--;
|
}
|
}
|
}
|
|
/// <summary>check is there any sender can be used to send
|
/// </summary>
|
/// <returns></returns>
|
public bool hasValidSender()
|
{
|
foreach (IClientChannel sender in this._senders)
|
{
|
if (sender.IsConnected)
|
return true;
|
}
|
return false;
|
}
|
/// <summary>send message and wait reply
|
/// </summary>
|
/// <param name="message"></param>
|
/// <returns></returns>
|
public IDictionary<string, object> SendAndWait(IDictionary<string, object> message)
|
{
|
return this.SendAndWait(message, Endpoint.TIMEOUT);
|
}
|
/// <summary>send message and wait reply
|
/// </summary>
|
/// <param name="message"></param>
|
/// <param name="timeout">timeout in milliseconds</param>
|
/// <returns></returns>
|
public IDictionary<string, object> SendAndWait(IDictionary<string, object> message, int timeout)
|
{
|
return this.SendAndWait(null, message, timeout);
|
}
|
/// <summary>send message and wait reply
|
/// </summary>
|
/// <param name="sender">use to send, must belong this proxy</param>
|
/// <param name="message"></param>
|
/// <param name="timeout">timeout in milliseconds</param>
|
/// <returns></returns>
|
internal IDictionary<string, object> SendAndWait(IChannelSender sender, IDictionary<string, object> message, int timeout)
|
{
|
return this._handler.SendAndWait(this,
|
this.GetSender(sender),
|
this.CreateMessage(message),
|
timeout);
|
}
|
/// <summary>send message
|
/// </summary>
|
/// <param name="message"></param>
|
public void Send(IDictionary<string, object> message)
|
{
|
this.Send(null, message);
|
}
|
/// <summary>send message
|
/// </summary>
|
/// <param name="sender">use to send, must belong this proxy</param>
|
/// <param name="message"></param>
|
internal void Send(IChannelSender sender, IDictionary<string, object> message)
|
{
|
this._handler.Send(this.CreateMessage(message), this.GetSender(sender));
|
}
|
|
private Message CreateMessage(IDictionary<string, object> 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)];
|
}
|
}
|
}
|