using System;
|
using System.Collections.Generic;
|
using System.Text;
|
using WebSocketSharp;
|
using WebSocketSharp.Frame;
|
|
namespace Taobao.Top.Link.Channel.WebSocket
|
{
|
/// <summary>websocket clientchannel via websocket-sharp impl
|
/// </summary>
|
public class WebSocketClientChannel : IClientChannel
|
{
|
private WebSocketSharp.WebSocket _socket;
|
private ResetableTimer _timer;
|
private EventHandler<ChannelContext> _onMessage;
|
private EventHandler<ChannelContext> _onError;
|
private EventHandler<ChannelClosedEventArgs> _onClosed;
|
|
public EventHandler<ChannelContext> OnMessage
|
{
|
get { this.DelayPing(); return this._onMessage; }
|
set { this._onMessage = value; }
|
}
|
public EventHandler<ChannelContext> OnError
|
{
|
get { this.DelayPing(); return this._onError; }
|
set { this._onError = value; }
|
}
|
public EventHandler<ChannelClosedEventArgs> OnClosed
|
{
|
get { return this._onClosed; }
|
set { this._onClosed = value; }
|
}
|
|
public Uri Uri { get; set; }
|
public bool IsConnected { get { return this._socket.ReadyState == WsState.OPEN; } }
|
|
public WebSocketClientChannel(WebSocketSharp.WebSocket socket)
|
{
|
this._socket = socket;
|
this._onClosed += (o, e) =>
|
{
|
this.Close(e.Reason);
|
};
|
}
|
|
public void Send(byte[] data)
|
{
|
this.CheckChannel();
|
this._socket.Send(data);
|
}
|
|
public void Close(string reason)
|
{
|
this._socket.Close(CloseStatusCode.NORMAL, reason);
|
if (this._timer != null)
|
{
|
this._timer.Cancel();
|
this._timer = null;
|
#if DEBUG
|
Console.WriteLine("TMC: Info@close: " + reason);
|
#endif
|
}
|
}
|
|
public ResetableTimer HeartbeatTimer
|
{
|
set
|
{
|
this._timer = value;
|
this._timer.Elapsed += (s, e) =>
|
{
|
if (this.IsConnected)
|
//websocket-sharp's ping is sync
|
this._socket.Ping();
|
};
|
}
|
}
|
|
private void CheckChannel()
|
{
|
if (!this.IsConnected)
|
{
|
if (this._timer != null)
|
this._timer.Cancel();
|
throw new LinkException("websocket channel closed");
|
}
|
this.DelayPing();
|
}
|
private void DelayPing()
|
{
|
try
|
{
|
if (this._timer != null)
|
this._timer.Delay();
|
}
|
catch (Exception)
|
{
|
|
}
|
}
|
}
|
}
|