using System;
using System.Collections.Generic;
using Taobao.Top.Link.Channel.WebSocket;
using Top.Api;
namespace Taobao.Top.Link.Channel
{
/// a channel pool that same uri sharing same channel
///
public class ClientChannelSharedSelector : IClientChannelSelector
{
private static readonly int CONNECTTIMEOUT = 5000;
private ITopLogger _logger;
private Object _lockObject;
private IDictionary _channels;
/// get or set heartbeat interval time in milliseconds
///
public int HeartbeatPeriod { get; set; }
public ClientChannelSharedSelector() : this(Log.Instance) { }
public ClientChannelSharedSelector(ITopLogger logger)
{
this._logger = logger;
this._lockObject = new object();
this._channels = new Dictionary();
}
public IClientChannel GetChannel(Uri uri)
{
if (!uri.Scheme.Equals("ws", StringComparison.InvariantCultureIgnoreCase))
return null;
var url = uri.ToString();
if (!this.HaveChannel(url))
lock (this._lockObject)
if (!this.HaveChannel(url))
this.AddChannel(url, this.WrapChannel(this.Connect(uri, CONNECTTIMEOUT)));
return _channels[url];
}
public void ReturnChannel(IClientChannel channel) { }
protected virtual IClientChannel Connect(Uri uri, int timeout)
{
return WebSocketClient.Connect(this._logger, uri, timeout);
}
private IClientChannel WrapChannel(IClientChannel channel)
{
if (this.HeartbeatPeriod > 0)
channel.HeartbeatTimer = new ResetableTimer(this.HeartbeatPeriod);
return channel;
}
private bool HaveChannel(string url)
{
return this._channels.ContainsKey(url) && this._channels[url].IsConnected;
}
private void AddChannel(string url, IClientChannel channel)
{
if (this._channels.ContainsKey(url))
this._channels[url] = channel;
else
this._channels.Add(url, channel);
}
}
}