Added NightAlert project for travel kit

This commit is contained in:
2021-06-10 14:39:06 -04:00
commit d38d9e3b7e
308 changed files with 35922 additions and 0 deletions

View File

@@ -0,0 +1,26 @@
using System;
namespace Quobject.EngineIoClientDotNet.Client
{
public class EngineIOException : Exception
{
public string Transport;
public object code;
public EngineIOException(string message)
: base(message)
{
}
public EngineIOException(Exception cause)
: base("", cause)
{
}
public EngineIOException(string message, Exception cause)
: base(message, cause)
{
}
}
}

View File

@@ -0,0 +1,33 @@
using Newtonsoft.Json.Linq;
using System.Collections.Immutable;
namespace Quobject.EngineIoClientDotNet.Client
{
public class HandshakeData
{
public string Sid;
public ImmutableList<string> Upgrades = ImmutableList<string>.Empty;
public long PingInterval;
public long PingTimeout;
public HandshakeData(string data)
: this(JObject.Parse(data))
{
}
public HandshakeData(JObject data)
{
var upgrades = data.GetValue("upgrades");
foreach (var e in upgrades)
{
Upgrades = Upgrades.Add(e.ToString());
}
Sid = data.GetValue("sid").Value<string>();
PingInterval = data.GetValue("pingInterval").Value<long>();
PingTimeout = data.GetValue("pingTimeout").Value<long>();
}
}
}

View File

@@ -0,0 +1,35 @@
using System.Collections.Concurrent;
using System.Collections.Generic;
using Newtonsoft.Json.Linq;
namespace Quobject.EngineIoClientDotNet.Client
{
public class HandshakeData
{
public string Sid;
public List<string> Upgrades = new List<string>();
public long PingInterval;
public long PingTimeout;
public HandshakeData(string data)
: this(JObject.Parse(data))
{
}
public HandshakeData(JObject data)
{
var upgrades = data.GetValue("upgrades");
foreach (var e in upgrades)
{
Upgrades.Add(e.ToString());
}
Sid = data.GetValue("sid").Value<string>();
PingInterval = data.GetValue("pingInterval").Value<long>();
PingTimeout = data.GetValue("pingTimeout").Value<long>();
}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,212 @@

using System.Text;
using System.Collections.Immutable;
using Quobject.EngineIoClientDotNet.ComponentEmitter;
using Quobject.EngineIoClientDotNet.Modules;
using Quobject.EngineIoClientDotNet.Parser;
using System;
using System.Collections.Generic;
namespace Quobject.EngineIoClientDotNet.Client
{
public abstract class Transport : Emitter
{
protected enum ReadyStateEnum
{
OPENING,
OPEN,
CLOSED,
PAUSED
}
public static readonly string EVENT_OPEN = "open";
public static readonly string EVENT_CLOSE = "close";
public static readonly string EVENT_PACKET = "packet";
public static readonly string EVENT_DRAIN = "drain";
public static readonly string EVENT_ERROR = "error";
public static readonly string EVENT_SUCCESS = "success";
public static readonly string EVENT_DATA = "data";
public static readonly string EVENT_REQUEST_HEADERS = "requestHeaders";
public static readonly string EVENT_RESPONSE_HEADERS = "responseHeaders";
protected static int Timestamps = 0;
private bool _writeable ;
public bool Writable {
get { return _writeable; }
set
{
var log = LogManager.GetLogger(Global.CallerName());
log.Info(string.Format("Writable: {0} sid={1}", value, this.Socket.Id));
_writeable = value;
}
}
private int myVar;
public int MyProperty
{
get { return myVar; }
set { myVar = value; }
}
public string Name;
public Dictionary<string, string> Query;
protected bool Secure;
protected bool TimestampRequests;
protected int Port;
protected string Path;
protected string Hostname;
protected string TimestampParam;
protected Socket Socket;
protected bool Agent = false;
protected bool ForceBase64 = false;
protected bool ForceJsonp = false;
protected string Cookie;
protected Dictionary<string, string> ExtraHeaders;
protected ReadyStateEnum ReadyState = ReadyStateEnum.CLOSED;
protected Transport(Options options)
{
this.Path = options.Path;
this.Hostname = options.Hostname;
this.Port = options.Port;
this.Secure = options.Secure;
this.Query = options.Query;
this.TimestampParam = options.TimestampParam;
this.TimestampRequests = options.TimestampRequests;
this.Socket = options.Socket;
this.Agent = options.Agent;
this.ForceBase64 = options.ForceBase64;
this.ForceJsonp = options.ForceJsonp;
this.Cookie = options.GetCookiesAsString();
this.ExtraHeaders = options.ExtraHeaders;
}
protected Transport OnError(string message, Exception exception)
{
Exception err = new EngineIOException(message, exception);
this.Emit(EVENT_ERROR, err);
return this;
}
protected void OnOpen()
{
ReadyState = ReadyStateEnum.OPEN;
Writable = true;
Emit(EVENT_OPEN);
}
protected void OnClose()
{
ReadyState = ReadyStateEnum.CLOSED;
Emit(EVENT_CLOSE);
}
protected virtual void OnData(string data)
{
this.OnPacket(Parser.Parser.DecodePacket(data));
}
protected virtual void OnData(byte[] data)
{
this.OnPacket(Parser.Parser.DecodePacket(data));
}
protected void OnPacket(Packet packet)
{
this.Emit(EVENT_PACKET, packet);
}
public Transport Open()
{
if (ReadyState == ReadyStateEnum.CLOSED)
{
ReadyState = ReadyStateEnum.OPENING;
DoOpen();
}
return this;
}
public Transport Close()
{
if (ReadyState == ReadyStateEnum.OPENING || ReadyState == ReadyStateEnum.OPEN)
{
DoClose();
OnClose();
}
return this;
}
public Transport Send(ImmutableList<Packet> packets)
{
var log = LogManager.GetLogger(Global.CallerName());
log.Info("Send called with packets.Count: " + packets.Count);
var count = packets.Count;
if (ReadyState == ReadyStateEnum.OPEN)
{
//PollTasks.Exec((n) =>
//{
Write(packets);
//});
}
else
{
throw new EngineIOException("Transport not open");
//log.Info("Transport not open");
}
return this;
}
protected abstract void DoOpen();
protected abstract void DoClose();
protected abstract void Write(ImmutableList<Packet> packets);
public class Options
{
public bool Agent = false;
public bool ForceBase64 = false;
public bool ForceJsonp = false;
public string Hostname;
public string Path;
public string TimestampParam;
public bool Secure = false;
public bool TimestampRequests = true;
public int Port;
public int PolicyPort;
public Dictionary<string, string> Query;
public bool IgnoreServerCertificateValidation = false;
internal Socket Socket;
public Dictionary<string, string> Cookies = new Dictionary<string, string>();
public Dictionary<string, string> ExtraHeaders = new Dictionary<string, string>();
public string GetCookiesAsString()
{
var result = new StringBuilder();
var first = true;
foreach (var item in Cookies)
{
if (!first)
{
result.Append("; ");
}
result.Append(string.Format("{0}={1}", item.Key, item.Value));
first = false;
}
return result.ToString();
}
}
}
}

View File

@@ -0,0 +1,209 @@

using System.Collections.Concurrent;
using System.Text;
using Quobject.EngineIoClientDotNet.ComponentEmitter;
using Quobject.EngineIoClientDotNet.Modules;
using Quobject.EngineIoClientDotNet.Parser;
using System;
using System.Collections.Generic;
namespace Quobject.EngineIoClientDotNet.Client
{
public abstract class Transport : Emitter
{
protected enum ReadyStateEnum
{
OPENING,
OPEN,
CLOSED,
PAUSED
}
public static readonly string EVENT_OPEN = "open";
public static readonly string EVENT_CLOSE = "close";
public static readonly string EVENT_PACKET = "packet";
public static readonly string EVENT_DRAIN = "drain";
public static readonly string EVENT_ERROR = "error";
public static readonly string EVENT_SUCCESS = "success";
public static readonly string EVENT_DATA = "data";
public static readonly string EVENT_REQUEST_HEADERS = "requestHeaders";
public static readonly string EVENT_RESPONSE_HEADERS = "responseHeaders";
protected static int Timestamps = 0;
private bool _writeable ;
public bool Writable {
get { return _writeable; }
set
{
var log = LogManager.GetLogger(Global.CallerName());
log.Info(string.Format("Writable: {0} sid={1}", value, this.Socket.Id));
_writeable = value;
}
}
private int myVar;
public int MyProperty
{
get { return myVar; }
set { myVar = value; }
}
public string Name;
public Dictionary<string, string> Query;
protected bool Secure;
protected bool TimestampRequests;
protected int Port;
protected string Path;
protected string Hostname;
protected string TimestampParam;
protected Socket Socket;
protected bool Agent = false;
protected bool ForceBase64 = false;
protected bool ForceJsonp = false;
protected string Cookie;
protected ReadyStateEnum ReadyState = ReadyStateEnum.CLOSED;
protected Transport(Options options)
{
this.Path = options.Path;
this.Hostname = options.Hostname;
this.Port = options.Port;
this.Secure = options.Secure;
this.Query = options.Query;
this.TimestampParam = options.TimestampParam;
this.TimestampRequests = options.TimestampRequests;
this.Socket = options.Socket;
this.Agent = options.Agent;
this.ForceBase64 = options.ForceBase64;
this.ForceJsonp = options.ForceJsonp;
this.Cookie = options.GetCookiesAsString();
}
protected Transport OnError(string message, Exception exception)
{
Exception err = new EngineIOException(message, exception);
this.Emit(EVENT_ERROR, err);
return this;
}
protected void OnOpen()
{
ReadyState = ReadyStateEnum.OPEN;
Writable = true;
Emit(EVENT_OPEN);
}
protected void OnClose()
{
ReadyState = ReadyStateEnum.CLOSED;
Emit(EVENT_CLOSE);
}
protected virtual void OnData(string data)
{
this.OnPacket(Parser.Parser.DecodePacket(data));
}
protected virtual void OnData(byte[] data)
{
this.OnPacket(Parser.Parser.DecodePacket(data));
}
protected void OnPacket(Packet packet)
{
this.Emit(EVENT_PACKET, packet);
}
public Transport Open()
{
if (ReadyState == ReadyStateEnum.CLOSED)
{
ReadyState = ReadyStateEnum.OPENING;
DoOpen();
}
return this;
}
public Transport Close()
{
if (ReadyState == ReadyStateEnum.OPENING || ReadyState == ReadyStateEnum.OPEN)
{
DoClose();
OnClose();
}
return this;
}
public Transport Send(List<Packet> packets)
{
var log = LogManager.GetLogger(Global.CallerName());
log.Info("Send called with packets.Count: " + packets.Count);
var count = packets.Count;
if (ReadyState == ReadyStateEnum.OPEN)
{
//PollTasks.Exec((n) =>
//{
Write(packets);
//});
}
else
{
throw new EngineIOException("Transport not open");
//log.Info("Transport not open");
}
return this;
}
protected abstract void DoOpen();
protected abstract void DoClose();
protected abstract void Write(List<Packet> packets);
public class Options
{
public bool Agent = false;
public bool ForceBase64 = false;
public bool ForceJsonp = false;
public string Hostname;
public string Path;
public string TimestampParam;
public bool Secure = false;
public bool TimestampRequests = true;
public int Port;
public int PolicyPort;
public Dictionary<string, string> Query;
public bool IgnoreServerCertificateValidation = false;
internal Socket Socket;
public Dictionary<string, string> Cookies = new Dictionary<string, string>();
public string GetCookiesAsString()
{
var result = new StringBuilder();
var first = true;
foreach (var item in Cookies)
{
if (!first)
{
result.Append("; ");
}
result.Append(string.Format("{0}={1}", item.Key, item.Value));
first = false;
}
return result.ToString();
}
}
}
}

View File

@@ -0,0 +1,380 @@

using System.Collections.Immutable;
using Quobject.EngineIoClientDotNet.ComponentEmitter;
using Quobject.EngineIoClientDotNet.Modules;
using Quobject.EngineIoClientDotNet.Parser;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Quobject.EngineIoClientDotNet.Client.Transports
{
public class Polling : Transport
{
public static readonly string NAME = "polling";
public static readonly string EVENT_POLL = "poll";
public static readonly string EVENT_POLL_COMPLETE = "pollComplete";
private bool IsPolling = false;
public Polling(Options opts) : base(opts)
{
Name = NAME;
}
private bool FirstTimePoll = true;
private bool OnDataReceived = false;
protected override void DoOpen()
{
var log = LogManager.GetLogger(Global.CallerName());
log.Info("DoOpen: Entry");
do
{
if (FirstTimePoll)
{
log.Info("DoOpen: Initial Poll - ReadyState=" + ReadyState.ToString());
FirstTimePoll = false;
Poll();
IsPolling = false;
Emit(EVENT_POLL_COMPLETE);
}
else if (OnDataReceived && ReadyState == ReadyStateEnum.OPEN)
{
log.Info("DoOpen: General Poll - ReadyState=" + ReadyState.ToString());
OnDataReceived = false;// Don't poll again, unless signaled by _onData
Poll();
IsPolling = false;
Emit(EVENT_POLL_COMPLETE);
}
else
{
log.Info(string.Format("DoOpen: ignoring poll - transport state {0}", ReadyState));
}
System.Threading.Thread.Sleep(100);
}
while (ReadyState != ReadyStateEnum.CLOSED);
}
public void Pause(Action onPause)
{
//var log = LogManager.GetLogger(Global.CallerName());
ReadyState = ReadyStateEnum.PAUSED;
Action pause = () =>
{
//log.Info("paused");
ReadyState = ReadyStateEnum.PAUSED;
onPause();
};
if (IsPolling || !Writable)
{
var total = new[] {0};
if (IsPolling)
{
//log.Info("we are currently polling - waiting to pause");
total[0]++;
Once(EVENT_POLL_COMPLETE, new PauseEventPollCompleteListener(total, pause));
}
if (!Writable)
{
//log.Info("we are currently writing - waiting to pause");
total[0]++;
Once(EVENT_DRAIN, new PauseEventDrainListener(total, pause));
}
}
else
{
pause();
}
}
public void Resume()
{
if (ReadyState == ReadyStateEnum.PAUSED)
ReadyState = ReadyStateEnum.OPEN;
}
private class PauseEventDrainListener : IListener
{
private int[] total;
private Action pause;
public PauseEventDrainListener(int[] total, Action pause)
{
this.total = total;
this.pause = pause;
}
public void Call(params object[] args)
{
//var log = LogManager.GetLogger(Global.CallerName());
//log.Info("pre-pause writing complete");
if (--total[0] == 0)
{
pause();
}
}
public int CompareTo(IListener other)
{
return this.GetId().CompareTo(other.GetId());
}
public int GetId()
{
return 0;
}
}
class PauseEventPollCompleteListener : IListener
{
private int[] total;
private Action pause;
public PauseEventPollCompleteListener(int[] total, Action pause)
{
this.total = total;
this.pause = pause;
}
public void Call(params object[] args)
{
//var log = LogManager.GetLogger(Global.CallerName());
//log.Info("pre-pause polling complete");
if (--total[0] == 0)
{
pause();
}
}
public int CompareTo(IListener other)
{
return this.GetId().CompareTo(other.GetId());
}
public int GetId()
{
return 0;
}
}
private void Poll()
{
//var log = LogManager.GetLogger(Global.CallerName());
//log.Info("polling");
IsPolling = true;
DoPoll();
Emit(EVENT_POLL);
}
protected override void OnData(string data)
{
_onData(data);
}
protected override void OnData(byte[] data)
{
_onData(data);
}
private class DecodePayloadCallback : IDecodePayloadCallback
{
private Polling polling;
public DecodePayloadCallback(Polling polling)
{
this.polling = polling;
}
public bool Call(Packet packet, int index, int total)
{
if (polling.ReadyState == ReadyStateEnum.OPENING)
{
polling.OnOpen();
}
if (packet.Type == Packet.CLOSE)
{
polling.OnClose();
return false;
}
polling.OnPacket(packet);
return true;
}
}
private void _onData(object data)
{
var log = LogManager.GetLogger(Global.CallerName());
log.Info(string.Format("polling got data {0}",data));
var callback = new DecodePayloadCallback(this);
if (data is string)
{
Parser.Parser.DecodePayload((string)data, callback);
}
else if (data is byte[])
{
Parser.Parser.DecodePayload((byte[])data, callback);
}
// Signal that data was received
OnDataReceived = true;
}
private class CloseListener : IListener
{
private Polling polling;
public CloseListener(Polling polling)
{
this.polling = polling;
}
public void Call(params object[] args)
{
//var log = LogManager.GetLogger(Global.CallerName());
//log.Info("writing close packet");
ImmutableList<Packet> packets = ImmutableList<Packet>.Empty;
packets = packets.Add(new Packet(Packet.CLOSE));
polling.Write(packets);
}
public int CompareTo(IListener other)
{
return this.GetId().CompareTo(other.GetId());
}
public int GetId()
{
return 0;
}
}
protected override void DoClose()
{
var log = LogManager.GetLogger(Global.CallerName());
var closeListener = new CloseListener(this);
if (ReadyState == ReadyStateEnum.OPEN)
{
log.Info("transport open - closing");
closeListener.Call();
}
else
{
// in case we're trying to close while
// handshaking is in progress (engine.io-client GH-164)
log.Info("transport not open - deferring close");
this.Once(EVENT_OPEN, closeListener);
}
}
public class SendEncodeCallback : IEncodeCallback
{
private Polling polling;
public SendEncodeCallback(Polling polling)
{
this.polling = polling;
}
public void Call(object data)
{
//var log = LogManager.GetLogger(Global.CallerName());
//log.Info("SendEncodeCallback data = " + data);
var byteData = (byte[]) data;
polling.DoWrite(byteData, () =>
{
polling.Writable = true;
polling.Emit(EVENT_DRAIN);
});
}
}
protected override void Write(ImmutableList<Packet> packets)
{
var log = LogManager.GetLogger(Global.CallerName());
log.Info("Write packets.Count = " + packets.Count);
Writable = false;
var callback = new SendEncodeCallback(this);
Parser.Parser.EncodePayload(packets.ToArray(), callback);
}
public string Uri()
{
//var query = this.Query;
var query = new Dictionary<string, string>(Query);
//if (Query == null)
//{
// query = new Dictionary<string, string>();
//}
string schema = this.Secure ? "https" : "http";
string portString = "";
if (this.TimestampRequests)
{
query.Add(this.TimestampParam, DateTime.Now.Ticks + "-" + Transport.Timestamps++);
}
query.Add("b64", "1");
string _query = ParseQS.Encode(query);
if (this.Port > 0 && (("https" == schema && this.Port != 443)
|| ("http" == schema && this.Port != 80)))
{
portString = ":" + this.Port;
}
if (_query.Length > 0)
{
_query = "?" + _query;
}
return schema + "://" + this.Hostname + portString + this.Path + _query;
}
protected virtual void DoWrite(byte[] data, Action action)
{
}
protected virtual void DoPoll()
{
}
}
}

View File

@@ -0,0 +1,434 @@

using Quobject.EngineIoClientDotNet.ComponentEmitter;
using Quobject.EngineIoClientDotNet.Modules;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Threading.Tasks;
namespace Quobject.EngineIoClientDotNet.Client.Transports
{
public class PollingXHR : Polling
{
private XHRRequest sendXhr;
public PollingXHR(Options options) : base(options)
{
}
protected XHRRequest Request()
{
return Request(null);
}
protected XHRRequest Request(XHRRequest.RequestOptions opts)
{
if (opts == null)
{
opts = new XHRRequest.RequestOptions();
}
opts.Uri = Uri();
opts.ExtraHeaders = this.ExtraHeaders;
XHRRequest req = new XHRRequest(opts);
req.On(EVENT_REQUEST_HEADERS, new EventRequestHeadersListener(this)).
On(EVENT_RESPONSE_HEADERS, new EventResponseHeadersListener(this));
return req;
}
class EventRequestHeadersListener : IListener
{
private PollingXHR pollingXHR;
public EventRequestHeadersListener(PollingXHR pollingXHR)
{
this.pollingXHR = pollingXHR;
}
public void Call(params object[] args)
{
// Never execute asynchronously for support to modify headers.
pollingXHR.Emit(EVENT_REQUEST_HEADERS, args[0]);
}
public int CompareTo(IListener other)
{
return this.GetId().CompareTo(other.GetId());
}
public int GetId()
{
return 0;
}
}
class EventResponseHeadersListener : IListener
{
private PollingXHR pollingXHR;
public EventResponseHeadersListener(PollingXHR pollingXHR)
{
this.pollingXHR = pollingXHR;
}
public void Call(params object[] args)
{
pollingXHR.Emit(EVENT_RESPONSE_HEADERS, args[0]);
}
public int CompareTo(IListener other)
{
return this.GetId().CompareTo(other.GetId());
}
public int GetId()
{
return 0;
}
}
protected override void DoWrite(byte[] data, Action action)
{
var opts = new XHRRequest.RequestOptions {Method = "POST", Data = data, CookieHeaderValue = Cookie};
var log = LogManager.GetLogger(Global.CallerName());
log.Info("DoWrite data = " + data);
Console.WriteLine("DoWrite data = " + data);
//try
//{
// var dataString = BitConverter.ToString(data);
// log.Info(string.Format("DoWrite data {0}", dataString));
//}
//catch (Exception e)
//{
// log.Error(e);
//}
sendXhr = Request(opts);
sendXhr.On(EVENT_SUCCESS, new SendEventSuccessListener(action));
sendXhr.On(EVENT_ERROR, new SendEventErrorListener(this));
sendXhr.Create();
}
class SendEventErrorListener : IListener
{
private PollingXHR pollingXHR;
public SendEventErrorListener(PollingXHR pollingXHR)
{
this.pollingXHR = pollingXHR;
}
public void Call(params object[] args)
{
Exception err = args.Length > 0 && args[0] is Exception ? (Exception) args[0] : null;
pollingXHR.OnError("xhr post error", err);
}
public int CompareTo(IListener other)
{
return this.GetId().CompareTo(other.GetId());
}
public int GetId()
{
return 0;
}
}
class SendEventSuccessListener : IListener
{
private Action action;
public SendEventSuccessListener(Action action)
{
this.action = action;
}
public void Call(params object[] args)
{
action();
}
public int CompareTo(IListener other)
{
return this.GetId().CompareTo(other.GetId());
}
public int GetId()
{
return 0;
}
}
protected override void DoPoll()
{
var log = LogManager.GetLogger(Global.CallerName());
log.Info("xhr DoPoll");
var opts = new XHRRequest.RequestOptions { CookieHeaderValue = Cookie };
sendXhr = Request(opts);
sendXhr.On(EVENT_DATA, new DoPollEventDataListener(this));
sendXhr.On(EVENT_ERROR, new DoPollEventErrorListener(this));
sendXhr.Create();
}
class DoPollEventDataListener : IListener
{
private PollingXHR pollingXHR;
public DoPollEventDataListener(PollingXHR pollingXHR)
{
this.pollingXHR = pollingXHR;
}
public void Call(params object[] args)
{
object arg = args.Length > 0 ? args[0] : null;
if (arg is string)
{
pollingXHR.OnData((string)arg);
}
else if (arg is byte[])
{
pollingXHR.OnData((byte[])arg);
}
}
public int CompareTo(IListener other)
{
return this.GetId().CompareTo(other.GetId());
}
public int GetId()
{
return 0;
}
}
class DoPollEventErrorListener : IListener
{
private PollingXHR pollingXHR;
public DoPollEventErrorListener(PollingXHR pollingXHR)
{
this.pollingXHR = pollingXHR;
}
public void Call(params object[] args)
{
Exception err = args.Length > 0 && args[0] is Exception ? (Exception)args[0] : null;
pollingXHR.OnError("xhr poll error", err);
}
public int CompareTo(IListener other)
{
return this.GetId().CompareTo(other.GetId());
}
public int GetId()
{
return 0;
}
}
public class XHRRequest : Emitter
{
private string Method;
private string Uri;
private byte[] Data;
private string CookieHeaderValue;
private HttpWebRequest Xhr;
private Dictionary<string, string> ExtraHeaders;
public XHRRequest(RequestOptions options)
{
Method = options.Method ?? "GET";
Uri = options.Uri;
Data = options.Data;
CookieHeaderValue = options.CookieHeaderValue;
ExtraHeaders = options.ExtraHeaders;
}
public void Create()
{
var log = LogManager.GetLogger(Global.CallerName());
try
{
log.Info(string.Format("xhr open {0}: {1}", Method, Uri));
Xhr = (HttpWebRequest) WebRequest.Create(Uri);
Xhr.Method = Method;
if (CookieHeaderValue != null)
{
Xhr.Headers.Add("Cookie", CookieHeaderValue);
}
if (ExtraHeaders != null)
{
foreach (var header in ExtraHeaders)
{
Xhr.Headers.Add(header.Key, header.Value);
}
}
}
catch (Exception e)
{
log.Error(e);
OnError(e);
return;
}
if (Method == "POST")
{
Xhr.ContentType = "application/octet-stream";
}
try
{
if (Data != null)
{
Xhr.ContentLength = Data.Length;
using (var requestStream = Xhr.GetRequestStream())
{
requestStream.WriteAsync(Data, 0, Data.Length).Wait();
}
}
Task.Run(() =>
{
var log2 = LogManager.GetLogger(Global.CallerName());
log2.Info("Task.Run Create start");
using (var res = Xhr.GetResponse())
{
log.Info("Xhr.GetResponse ");
var responseHeaders = new Dictionary<string, string>();
for (int i = 0; i < res.Headers.Count; i++)
{
responseHeaders.Add(res.Headers.Keys[i], res.Headers[i]);
}
OnResponseHeaders(responseHeaders);
var contentType = res.Headers["Content-Type"];
using (var resStream = res.GetResponseStream())
{
Debug.Assert(resStream != null, "resStream != null");
if (contentType.Equals("application/octet-stream",
StringComparison.OrdinalIgnoreCase))
{
var buffer = new byte[16 * 1024];
using (var ms = new MemoryStream())
{
int read;
while ((read = resStream.Read(buffer, 0, buffer.Length)) > 0)
{
ms.Write(buffer, 0, read);
}
var a = ms.ToArray();
OnData(a);
}
}
else
{
using (var sr = new StreamReader(resStream))
{
OnData(sr.ReadToEnd());
}
}
}
}
log2.Info("Task.Run Create finish");
}).Wait();
}
catch (System.IO.IOException e)
{
log.Error("Create call failed", e);
OnError(e);
}
catch (System.Net.WebException e)
{
log.Error("Create call failed", e);
OnError(e);
}
catch (Exception e)
{
log.Error("Create call failed", e);
OnError(e);
}
}
private void OnSuccess()
{
this.Emit(EVENT_SUCCESS);
}
private void OnData(string data)
{
var log = LogManager.GetLogger(Global.CallerName());
log.Info("OnData string = " + data);
this.Emit(EVENT_DATA, data);
this.OnSuccess();
}
private void OnData(byte[] data)
{
var log = LogManager.GetLogger(Global.CallerName());
log.Info("OnData byte[] =" + System.Text.UTF8Encoding.UTF8.GetString(data));
this.Emit(EVENT_DATA, data);
this.OnSuccess();
}
private void OnError(Exception err)
{
this.Emit(EVENT_ERROR, err);
}
private void OnRequestHeaders(Dictionary<string, string> headers)
{
this.Emit(EVENT_REQUEST_HEADERS, headers);
}
private void OnResponseHeaders(Dictionary<string, string> headers)
{
this.Emit(EVENT_RESPONSE_HEADERS, headers);
}
public class RequestOptions
{
public string Uri;
public string Method;
public byte[] Data;
public string CookieHeaderValue;
public Dictionary<string, string> ExtraHeaders;
}
}
}
}

View File

@@ -0,0 +1,428 @@

using Quobject.EngineIoClientDotNet.ComponentEmitter;
using Quobject.EngineIoClientDotNet.Modules;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Threading.Tasks;
namespace Quobject.EngineIoClientDotNet.Client.Transports
{
public class PollingXHR : Polling
{
private XHRRequest sendXhr;
public PollingXHR(Options options) : base(options)
{
}
protected XHRRequest Request()
{
return Request(null);
}
protected XHRRequest Request(XHRRequest.RequestOptions opts)
{
if (opts == null)
{
opts = new XHRRequest.RequestOptions();
}
opts.Uri = Uri();
XHRRequest req = new XHRRequest(opts);
req.On(EVENT_REQUEST_HEADERS, new EventRequestHeadersListener(this)).
On(EVENT_RESPONSE_HEADERS, new EventResponseHeadersListener(this));
return req;
}
class EventRequestHeadersListener : IListener
{
private PollingXHR pollingXHR;
public EventRequestHeadersListener(PollingXHR pollingXHR)
{
this.pollingXHR = pollingXHR;
}
public void Call(params object[] args)
{
// Never execute asynchronously for support to modify headers.
pollingXHR.Emit(EVENT_RESPONSE_HEADERS, args[0]);
}
public int CompareTo(IListener other)
{
return this.GetId().CompareTo(other.GetId());
}
public int GetId()
{
return 0;
}
}
class EventResponseHeadersListener : IListener
{
private PollingXHR pollingXHR;
public EventResponseHeadersListener(PollingXHR pollingXHR)
{
this.pollingXHR = pollingXHR;
}
public void Call(params object[] args)
{
pollingXHR.Emit(EVENT_REQUEST_HEADERS, args[0]);
}
public int CompareTo(IListener other)
{
return this.GetId().CompareTo(other.GetId());
}
public int GetId()
{
return 0;
}
}
protected override void DoWrite(byte[] data, Action action)
{
var opts = new XHRRequest.RequestOptions { Method = "POST", Data = data, CookieHeaderValue = Cookie };
var log = LogManager.GetLogger(Global.CallerName());
log.Info("DoWrite data = " + data);
//try
//{
// var dataString = BitConverter.ToString(data);
// log.Info(string.Format("DoWrite data {0}", dataString));
//}
//catch (Exception e)
//{
// log.Error(e);
//}
sendXhr = Request(opts);
sendXhr.On(EVENT_SUCCESS, new SendEventSuccessListener(action));
sendXhr.On(EVENT_ERROR, new SendEventErrorListener(this));
sendXhr.Create();
}
class SendEventErrorListener : IListener
{
private PollingXHR pollingXHR;
public SendEventErrorListener(PollingXHR pollingXHR)
{
this.pollingXHR = pollingXHR;
}
public void Call(params object[] args)
{
Exception err = args.Length > 0 && args[0] is Exception ? (Exception) args[0] : null;
pollingXHR.OnError("xhr post error", err);
}
public int CompareTo(IListener other)
{
return this.GetId().CompareTo(other.GetId());
}
public int GetId()
{
return 0;
}
}
class SendEventSuccessListener : IListener
{
private Action action;
public SendEventSuccessListener(Action action)
{
this.action = action;
}
public void Call(params object[] args)
{
action();
}
public int CompareTo(IListener other)
{
return this.GetId().CompareTo(other.GetId());
}
public int GetId()
{
return 0;
}
}
protected override void DoPoll()
{
var log = LogManager.GetLogger(Global.CallerName());
log.Info("xhr DoPoll");
var opts = new XHRRequest.RequestOptions { CookieHeaderValue = Cookie };
sendXhr = Request(opts);
sendXhr.On(EVENT_DATA, new DoPollEventDataListener(this));
sendXhr.On(EVENT_ERROR, new DoPollEventErrorListener(this));
sendXhr.Create();
}
class DoPollEventDataListener : IListener
{
private PollingXHR pollingXHR;
public DoPollEventDataListener(PollingXHR pollingXHR)
{
this.pollingXHR = pollingXHR;
}
public void Call(params object[] args)
{
object arg = args.Length > 0 ? args[0] : null;
if (arg is string)
{
pollingXHR.OnData((string)arg);
}
else if (arg is byte[])
{
pollingXHR.OnData((byte[])arg);
}
}
public int CompareTo(IListener other)
{
return this.GetId().CompareTo(other.GetId());
}
public int GetId()
{
return 0;
}
}
class DoPollEventErrorListener : IListener
{
private PollingXHR pollingXHR;
public DoPollEventErrorListener(PollingXHR pollingXHR)
{
this.pollingXHR = pollingXHR;
}
public void Call(params object[] args)
{
Exception err = args.Length > 0 && args[0] is Exception ? (Exception)args[0] : null;
pollingXHR.OnError("xhr poll error", err);
}
public int CompareTo(IListener other)
{
return this.GetId().CompareTo(other.GetId());
}
public int GetId()
{
return 0;
}
}
public class XHRRequest : Emitter
{
private string Method;
private string Uri;
private byte[] Data;
private string CookieHeaderValue;
private HttpWebRequest Xhr;
public XHRRequest(RequestOptions options)
{
Method = options.Method ?? "GET";
Uri = options.Uri;
Data = options.Data;
CookieHeaderValue = options.CookieHeaderValue;
}
public void Create()
{
var log = LogManager.GetLogger(Global.CallerName());
try
{
log.Info(string.Format("xhr open {0}: {1}", Method, Uri));
Xhr = (HttpWebRequest) WebRequest.Create(Uri);
Xhr.Method = Method;
if (CookieHeaderValue != null)
{
Xhr.Headers.Add("Cookie", CookieHeaderValue);
log.Info("added header " + CookieHeaderValue);
}
else
{
log.Info("not added header " + CookieHeaderValue);
}
}
catch (Exception e)
{
log.Error(e);
OnError(e);
return;
}
if (Method == "POST")
{
Xhr.ContentType = "application/octet-stream";
}
try
{
if (Data != null)
{
Xhr.ContentLength = Data.Length;
using (var requestStream = Xhr.GetRequestStream())
{
requestStream.Write(Data, 0, Data.Length);
}
}
Task.Run(() =>
{
var log2 = LogManager.GetLogger(Global.CallerName());
log2.Info("Task.Run Create start");
using (var res = Xhr.GetResponse())
{
log.Info("Xhr.GetResponse ");
var responseHeaders = new Dictionary<string, string>();
for (int i = 0; i < res.Headers.Count; i++)
{
responseHeaders.Add(res.Headers.Keys[i], res.Headers[i]);
}
OnResponseHeaders(responseHeaders);
var contentType = res.Headers["Content-Type"];
using (var resStream = res.GetResponseStream())
{
Debug.Assert(resStream != null, "resStream != null");
if (contentType.Equals("application/octet-stream",
StringComparison.OrdinalIgnoreCase))
{
var buffer = new byte[16 * 1024];
using (var ms = new MemoryStream())
{
int read;
while ((read = resStream.Read(buffer, 0, buffer.Length)) > 0)
{
ms.Write(buffer, 0, read);
}
var a = ms.ToArray();
OnData(a);
}
}
else
{
using (var sr = new StreamReader(resStream))
{
OnData(sr.ReadToEnd());
}
}
}
}
log2.Info("Task.Run Create finish");
}).Wait();
}
catch (System.IO.IOException e)
{
log.Error("Create call failed", e);
OnError(e);
}
catch (System.Net.WebException e)
{
log.Error("Create call failed", e);
OnError(e);
}
catch (Exception e)
{
log.Error("Create call failed", e);
OnError(e);
}
}
private void OnSuccess()
{
this.Emit(EVENT_SUCCESS);
}
private void OnData(string data)
{
var log = LogManager.GetLogger(Global.CallerName());
log.Info("OnData string = " + data);
this.Emit(EVENT_DATA, data);
this.OnSuccess();
}
private void OnData(byte[] data)
{
var log = LogManager.GetLogger(Global.CallerName());
log.Info("OnData byte[] =" + System.Text.UTF8Encoding.UTF8.GetString(data));
this.Emit(EVENT_DATA, data);
this.OnSuccess();
}
private void OnError(Exception err)
{
this.Emit(EVENT_ERROR, err);
}
private void OnRequestHeaders(Dictionary<string, string> headers)
{
this.Emit(EVENT_REQUEST_HEADERS, headers);
}
private void OnResponseHeaders(Dictionary<string, string> headers)
{
this.Emit(EVENT_RESPONSE_HEADERS, headers);
}
public class RequestOptions
{
public string Uri;
public string Method;
public byte[] Data;
public string CookieHeaderValue;
}
}
}
}

View File

@@ -0,0 +1,432 @@

using Quobject.EngineIoClientDotNet.ComponentEmitter;
using Quobject.EngineIoClientDotNet.Modules;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Threading.Tasks;
using Quobject.EngineIoClientDotNet.Thread;
namespace Quobject.EngineIoClientDotNet.Client.Transports
{
public class PollingXHR : Polling
{
private XHRRequest sendXhr;
public PollingXHR(Options options) : base(options)
{
}
protected XHRRequest Request()
{
return Request(null);
}
protected XHRRequest Request(XHRRequest.RequestOptions opts)
{
if (opts == null)
{
opts = new XHRRequest.RequestOptions();
}
opts.Uri = Uri();
XHRRequest req = new XHRRequest(opts);
req.On(EVENT_REQUEST_HEADERS, new EventRequestHeadersListener(this)).
On(EVENT_RESPONSE_HEADERS, new EventResponseHeadersListener(this));
return req;
}
class EventRequestHeadersListener : IListener
{
private PollingXHR pollingXHR;
public EventRequestHeadersListener(PollingXHR pollingXHR)
{
this.pollingXHR = pollingXHR;
}
public void Call(params object[] args)
{
// Never execute asynchronously for support to modify headers.
pollingXHR.Emit(EVENT_RESPONSE_HEADERS, args[0]);
}
public int CompareTo(IListener other)
{
return this.GetId().CompareTo(other.GetId());
}
public int GetId()
{
return 0;
}
}
class EventResponseHeadersListener : IListener
{
private PollingXHR pollingXHR;
public EventResponseHeadersListener(PollingXHR pollingXHR)
{
this.pollingXHR = pollingXHR;
}
public void Call(params object[] args)
{
pollingXHR.Emit(EVENT_REQUEST_HEADERS, args[0]);
}
public int CompareTo(IListener other)
{
return this.GetId().CompareTo(other.GetId());
}
public int GetId()
{
return 0;
}
}
protected override void DoWrite(byte[] data, Action action)
{
var opts = new XHRRequest.RequestOptions { Method = "POST", Data = data, CookieHeaderValue = Cookie };
var log = LogManager.GetLogger(Global.CallerName());
log.Info("DoWrite data = " + data);
//try
//{
// var dataString = BitConverter.ToString(data);
// log.Info(string.Format("DoWrite data {0}", dataString));
//}
//catch (Exception e)
//{
// log.Error(e);
//}
sendXhr = Request(opts);
sendXhr.On(EVENT_SUCCESS, new SendEventSuccessListener(action));
sendXhr.On(EVENT_ERROR, new SendEventErrorListener(this));
sendXhr.Create();
}
class SendEventErrorListener : IListener
{
private PollingXHR pollingXHR;
public SendEventErrorListener(PollingXHR pollingXHR)
{
this.pollingXHR = pollingXHR;
}
public void Call(params object[] args)
{
Exception err = args.Length > 0 && args[0] is Exception ? (Exception) args[0] : null;
pollingXHR.OnError("xhr post error", err);
}
public int CompareTo(IListener other)
{
return this.GetId().CompareTo(other.GetId());
}
public int GetId()
{
return 0;
}
}
class SendEventSuccessListener : IListener
{
private Action action;
public SendEventSuccessListener(Action action)
{
this.action = action;
}
public void Call(params object[] args)
{
action();
}
public int CompareTo(IListener other)
{
return this.GetId().CompareTo(other.GetId());
}
public int GetId()
{
return 0;
}
}
protected override void DoPoll()
{
var log = LogManager.GetLogger(Global.CallerName());
log.Info("xhr DoPoll");
var opts = new XHRRequest.RequestOptions { CookieHeaderValue = Cookie };
sendXhr = Request(opts);
sendXhr.On(EVENT_DATA, new DoPollEventDataListener(this));
sendXhr.On(EVENT_ERROR, new DoPollEventErrorListener(this));
sendXhr.Create();
}
class DoPollEventDataListener : IListener
{
private PollingXHR pollingXHR;
public DoPollEventDataListener(PollingXHR pollingXHR)
{
this.pollingXHR = pollingXHR;
}
public void Call(params object[] args)
{
object arg = args.Length > 0 ? args[0] : null;
if (arg is string)
{
pollingXHR.OnData((string)arg);
}
else if (arg is byte[])
{
pollingXHR.OnData((byte[])arg);
}
}
public int CompareTo(IListener other)
{
return this.GetId().CompareTo(other.GetId());
}
public int GetId()
{
return 0;
}
}
class DoPollEventErrorListener : IListener
{
private PollingXHR pollingXHR;
public DoPollEventErrorListener(PollingXHR pollingXHR)
{
this.pollingXHR = pollingXHR;
}
public void Call(params object[] args)
{
Exception err = args.Length > 0 && args[0] is Exception ? (Exception)args[0] : null;
pollingXHR.OnError("xhr poll error", err);
}
public int CompareTo(IListener other)
{
return this.GetId().CompareTo(other.GetId());
}
public int GetId()
{
return 0;
}
}
public class XHRRequest : Emitter
{
private string Method;
private string Uri;
private byte[] Data;
private string CookieHeaderValue;
private HttpWebRequest Xhr;
public XHRRequest(RequestOptions options)
{
Method = options.Method ?? "GET";
Uri = options.Uri;
Data = options.Data;
CookieHeaderValue = options.CookieHeaderValue;
}
public void Create()
{
var log = LogManager.GetLogger(Global.CallerName());
try
{
log.Info(string.Format("xhr open {0}: {1}", Method, Uri));
Xhr = (HttpWebRequest) WebRequest.Create(Uri);
Xhr.Method = Method;
Xhr.Timeout = 10*60*1000;
Xhr.ReadWriteTimeout = 10*60*1000;
if (CookieHeaderValue != null)
{
Xhr.Headers.Add("Cookie", CookieHeaderValue);
log.Info("added header " + CookieHeaderValue);
}
else
{
log.Info("not added header " + CookieHeaderValue);
}
}
catch (Exception e)
{
log.Error(e);
OnError(e);
return;
}
if (Method == "POST")
{
Xhr.ContentType = "application/octet-stream";
}
try
{
if (Data != null)
{
Xhr.ContentLength = Data.Length;
using (var requestStream = Xhr.GetRequestStream())
{
requestStream.Write(Data, 0, Data.Length);
}
}
EasyTimer.TaskRun(() =>
{
var log2 = LogManager.GetLogger(Global.CallerName());
log2.Info("Task.Run Create start");
using (var res = Xhr.GetResponse())
{
log.Info("Xhr.GetResponse ");
var responseHeaders = new Dictionary<string, string>();
for (int i = 0; i < res.Headers.Count; i++)
{
responseHeaders.Add(res.Headers.Keys[i], res.Headers[i]);
}
OnResponseHeaders(responseHeaders);
var contentType = res.Headers["Content-Type"];
using (var resStream = res.GetResponseStream())
{
Debug.Assert(resStream != null, "resStream != null");
if (contentType.Equals("application/octet-stream",
StringComparison.OrdinalIgnoreCase))
{
var buffer = new byte[16*1024];
using (var ms = new MemoryStream())
{
int read;
while ((read = resStream.Read(buffer, 0, buffer.Length)) > 0)
{
ms.Write(buffer, 0, read);
}
var a = ms.ToArray();
OnData(a);
}
}
else
{
using (var sr = new StreamReader(resStream))
{
OnData(sr.ReadToEnd());
}
}
}
}
log2.Info("Task.Run Create finish");
});
}
catch (System.IO.IOException e)
{
log.Error("Create call failed", e);
OnError(e);
}
catch (System.Net.WebException e)
{
log.Error("Create call failed", e);
OnError(e);
}
catch (Exception e)
{
log.Error("Create call failed", e);
OnError(e);
}
}
private void OnSuccess()
{
this.Emit(EVENT_SUCCESS);
}
private void OnData(string data)
{
var log = LogManager.GetLogger(Global.CallerName());
log.Info("OnData string = " + data);
this.Emit(EVENT_DATA, data);
this.OnSuccess();
}
private void OnData(byte[] data)
{
var log = LogManager.GetLogger(Global.CallerName());
log.Info("OnData byte[] =" + System.Text.UTF8Encoding.UTF8.GetString(data));
this.Emit(EVENT_DATA, data);
this.OnSuccess();
}
private void OnError(Exception err)
{
this.Emit(EVENT_ERROR, err);
}
private void OnRequestHeaders(Dictionary<string, string> headers)
{
this.Emit(EVENT_REQUEST_HEADERS, headers);
}
private void OnResponseHeaders(Dictionary<string, string> headers)
{
this.Emit(EVENT_RESPONSE_HEADERS, headers);
}
public class RequestOptions
{
public string Uri;
public string Method;
public byte[] Data;
public string CookieHeaderValue;
}
}
}
}

View File

@@ -0,0 +1,387 @@
using Quobject.EngineIoClientDotNet.ComponentEmitter;
using Quobject.EngineIoClientDotNet.Modules;
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using System.Linq;
using System.Text;
namespace Quobject.EngineIoClientDotNet.Client.Transports
{
public class PollingXHR : Polling
{
private XHRRequest sendXhr;
public PollingXHR(Options options)
: base(options)
{
}
protected XHRRequest Request()
{
return Request(null);
}
protected XHRRequest Request(XHRRequest.RequestOptions opts)
{
if (opts == null)
{
opts = new XHRRequest.RequestOptions();
}
opts.Uri = Uri();
var req = new XHRRequest(opts);
req.On(EVENT_REQUEST_HEADERS, new EventRequestHeadersListener(this)).
On(EVENT_RESPONSE_HEADERS, new EventResponseHeadersListener(this));
return req;
}
private class EventRequestHeadersListener : IListener
{
private PollingXHR pollingXHR;
public EventRequestHeadersListener(PollingXHR pollingXHR)
{
this.pollingXHR = pollingXHR;
}
public void Call(params object[] args)
{
// Never execute asynchronously for support to modify headers.
pollingXHR.Emit(EVENT_RESPONSE_HEADERS, args[0]);
}
public int CompareTo(IListener other)
{
return this.GetId().CompareTo(other.GetId());
}
public int GetId()
{
return 0;
}
}
private class EventResponseHeadersListener : IListener
{
private PollingXHR pollingXHR;
public EventResponseHeadersListener(PollingXHR pollingXHR)
{
this.pollingXHR = pollingXHR;
}
public void Call(params object[] args)
{
pollingXHR.Emit(EVENT_REQUEST_HEADERS, args[0]);
}
public int CompareTo(IListener other)
{
return this.GetId().CompareTo(other.GetId());
}
public int GetId()
{
return 0;
}
}
protected override void DoWrite(byte[] data, Action action)
{
var opts = new XHRRequest.RequestOptions { Method = "POST", Data = data, CookieHeaderValue = Cookie };
var log = LogManager.GetLogger(Global.CallerName());
log.Info("DoWrite data = " + data);
//try
//{
// var dataString = BitConverter.ToString(data);
// log.Info(string.Format("DoWrite data {0}", dataString));
//}
//catch (Exception e)
//{
// log.Error(e);
//}
sendXhr = Request(opts);
sendXhr.On(EVENT_SUCCESS, new SendEventSuccessListener(action));
sendXhr.On(EVENT_ERROR, new SendEventErrorListener(this));
sendXhr.Create();
}
private class SendEventErrorListener : IListener
{
private PollingXHR pollingXHR;
public SendEventErrorListener(PollingXHR pollingXHR)
{
this.pollingXHR = pollingXHR;
}
public void Call(params object[] args)
{
var err = args.Length > 0 && args[0] is Exception ? (Exception)args[0] : null;
pollingXHR.OnError("xhr post error", err);
}
public int CompareTo(IListener other)
{
return this.GetId().CompareTo(other.GetId());
}
public int GetId()
{
return 0;
}
}
private class SendEventSuccessListener : IListener
{
private Action action;
public SendEventSuccessListener(Action action)
{
this.action = action;
}
public void Call(params object[] args)
{
action?.Invoke();
}
public int CompareTo(IListener other)
{
return this.GetId().CompareTo(other.GetId());
}
public int GetId()
{
return 0;
}
}
protected override void DoPoll()
{
var log = LogManager.GetLogger(Global.CallerName());
log.Info("xhr poll");
var opts = new XHRRequest.RequestOptions { CookieHeaderValue = Cookie };
sendXhr = Request(opts);
sendXhr.On(EVENT_DATA, new DoPollEventDataListener(this));
sendXhr.On(EVENT_ERROR, new DoPollEventErrorListener(this));
//sendXhr.Create();
sendXhr.Create();
}
private class DoPollEventDataListener : IListener
{
private PollingXHR pollingXHR;
public DoPollEventDataListener(PollingXHR pollingXHR)
{
this.pollingXHR = pollingXHR;
}
public void Call(params object[] args)
{
var arg = args.Length > 0 ? args[0] : null;
if (arg is string)
{
pollingXHR.OnData((string)arg);
}
else if (arg is byte[])
{
pollingXHR.OnData((byte[])arg);
}
}
public int CompareTo(IListener other)
{
return this.GetId().CompareTo(other.GetId());
}
public int GetId()
{
return 0;
}
}
private class DoPollEventErrorListener : IListener
{
private PollingXHR pollingXHR;
public DoPollEventErrorListener(PollingXHR pollingXHR)
{
this.pollingXHR = pollingXHR;
}
public void Call(params object[] args)
{
var err = args.Length > 0 && args[0] is Exception ? (Exception)args[0] : null;
pollingXHR.OnError("xhr poll error", err);
}
public int CompareTo(IListener other)
{
return this.GetId().CompareTo(other.GetId());
}
public int GetId()
{
return 0;
}
}
public class XHRRequest : Emitter
{
private string Method;
private string Uri;
private byte[] Data;
private string CookieHeaderValue;
private Dictionary<string, string> ExtraHeaders;
public XHRRequest(RequestOptions options)
{
Method = options.Method ?? "GET";
Uri = options.Uri;
Data = options.Data;
CookieHeaderValue = options.CookieHeaderValue;
ExtraHeaders = options.ExtraHeaders;
}
public void Create()
{
var httpMethod = Method == "POST" ? HttpMethod.Post : HttpMethod.Get;
var dataToSend = Data == null ? Encoding.UTF8.GetBytes("") : Data;
Task.Run(async() =>
{
try
{
using (var httpClientHandler = new HttpClientHandler())
{
if (ServerCertificate.Ignore)
{
httpClientHandler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => { return true; };
}
using (var client = new HttpClient(httpClientHandler))
{
using (var httpContent = new ByteArrayContent(dataToSend))
{
if (Method == "POST")
{
httpContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/octet-stream");
}
var request = new HttpRequestMessage(httpMethod, Uri)
{
Content = httpContent
};
if (!string.IsNullOrEmpty(CookieHeaderValue))
{
httpContent.Headers.Add(@"Cookie", CookieHeaderValue);
}
if (ExtraHeaders != null)
{
foreach (var header in ExtraHeaders)
{
httpContent.Headers.Add(header.Key, header.Value);
}
}
if (Method == "GET")
{
using (HttpResponseMessage response = await client.GetAsync(request.RequestUri))
{
var responseContent = await response.Content.ReadAsStringAsync();
OnData(responseContent);
}
}
else
{
using (HttpResponseMessage response = await client.SendAsync(request))
{
response.EnsureSuccessStatusCode();
var contentType = response.Content.Headers.GetValues("Content-Type").Aggregate("", (acc, x) => acc + x).Trim();
if (contentType.Equals("application/octet-stream", StringComparison.OrdinalIgnoreCase))
{
var responseContent = await response.Content.ReadAsByteArrayAsync();
OnData(responseContent);
}
else
{
var responseContent = await response.Content.ReadAsStringAsync();
OnData(responseContent);
}
}
}
}
}
}
}
catch (Exception e)
{
OnError(e);
}
}).Wait();
}
private void OnSuccess()
{
this.Emit(EVENT_SUCCESS);
}
private void OnData(string data)
{
//var log = LogManager.GetLogger(Global.CallerName());
//log.Info("OnData string = " + data);
this.Emit(EVENT_DATA, data);
this.OnSuccess();
}
private void OnData(byte[] data)
{
//var log = LogManager.GetLogger(Global.CallerName());
//log.Info(string.Format("OnData byte[] ={0}", System.Text.Encoding.UTF8.GetString(data, 0, data.Length)));
this.Emit(EVENT_DATA, data);
this.OnSuccess();
}
private void OnError(Exception err)
{
this.Emit(EVENT_ERROR, err);
}
private void OnRequestHeaders(Dictionary<string, string> headers)
{
this.Emit(EVENT_REQUEST_HEADERS, headers);
}
private void OnResponseHeaders(Dictionary<string, string> headers)
{
this.Emit(EVENT_RESPONSE_HEADERS, headers);
}
public class RequestOptions
{
public string Uri;
public string Method;
public byte[] Data;
public string CookieHeaderValue;
public Dictionary<string, string> ExtraHeaders;
}
}
}
}

View File

@@ -0,0 +1,362 @@

using System.Collections.Concurrent;
using Quobject.EngineIoClientDotNet.ComponentEmitter;
using Quobject.EngineIoClientDotNet.Modules;
using Quobject.EngineIoClientDotNet.Parser;
using System;
using System.Collections.Generic;
using System.Linq;
using Quobject.EngineIoClientDotNet.Thread;
namespace Quobject.EngineIoClientDotNet.Client.Transports
{
public class Polling : Transport
{
public static readonly string NAME = "polling";
public static readonly string EVENT_POLL = "poll";
public static readonly string EVENT_POLL_COMPLETE = "pollComplete";
private bool IsPolling = false;
public Polling(Options opts) : base(opts)
{
Name = NAME;
}
protected override void DoOpen()
{
Poll();
}
public void Pause(Action onPause)
{
//var log = LogManager.GetLogger(Global.CallerName());
ReadyState = ReadyStateEnum.PAUSED;
Action pause = () =>
{
//log.Info("paused");
ReadyState = ReadyStateEnum.PAUSED;
onPause();
};
if (IsPolling || !Writable)
{
var total = new[] {0};
if (IsPolling)
{
//log.Info("we are currently polling - waiting to pause");
total[0]++;
Once(EVENT_POLL_COMPLETE, new PauseEventPollCompleteListener(total, pause));
}
if (!Writable)
{
//log.Info("we are currently writing - waiting to pause");
total[0]++;
Once(EVENT_DRAIN, new PauseEventDrainListener(total, pause));
}
}
else
{
pause();
}
}
private class PauseEventDrainListener : IListener
{
private int[] total;
private Action pause;
public PauseEventDrainListener(int[] total, Action pause)
{
this.total = total;
this.pause = pause;
}
public void Call(params object[] args)
{
//var log = LogManager.GetLogger(Global.CallerName());
//log.Info("pre-pause writing complete");
if (--total[0] == 0)
{
pause();
}
}
public int CompareTo(IListener other)
{
return this.GetId().CompareTo(other.GetId());
}
public int GetId()
{
return 0;
}
}
class PauseEventPollCompleteListener : IListener
{
private int[] total;
private Action pause;
public PauseEventPollCompleteListener(int[] total, Action pause)
{
this.total = total;
this.pause = pause;
}
public void Call(params object[] args)
{
//var log = LogManager.GetLogger(Global.CallerName());
//log.Info("pre-pause polling complete");
if (--total[0] == 0)
{
pause();
}
}
public int CompareTo(IListener other)
{
return this.GetId().CompareTo(other.GetId());
}
public int GetId()
{
return 0;
}
}
private void Poll()
{
var log = LogManager.GetLogger(Global.CallerName());
log.Info("polling");
IsPolling = true;
EasyTimer.TaskRunNoWait(DoPoll);
Emit(EVENT_POLL);
}
protected override void OnData(string data)
{
_onData(data);
}
protected override void OnData(byte[] data)
{
_onData(data);
}
private class DecodePayloadCallback : IDecodePayloadCallback
{
private Polling polling;
public DecodePayloadCallback(Polling polling)
{
this.polling = polling;
}
public bool Call(Packet packet, int index, int total)
{
if (polling.ReadyState == ReadyStateEnum.OPENING)
{
polling.OnOpen();
}
if (packet.Type == Packet.CLOSE)
{
polling.OnClose();
return false;
}
polling.OnPacket(packet);
return true;
}
}
private void _onData(object data)
{
var log = LogManager.GetLogger(Global.CallerName());
log.Info(string.Format("polling got data {0}",data));
var callback = new DecodePayloadCallback(this);
if (data is string)
{
Parser.Parser.DecodePayload((string)data, callback);
}
else if (data is byte[])
{
Parser.Parser.DecodePayload((byte[])data, callback);
}
if (ReadyState != ReadyStateEnum.CLOSED)
{
IsPolling = false;
log.Info("ReadyState != ReadyStateEnum.CLOSED");
Emit(EVENT_POLL_COMPLETE);
if (ReadyState == ReadyStateEnum.OPEN)
{
Poll();
}
else
{
log.Info(string.Format("ignoring poll - transport state {0}", ReadyState));
}
}
}
private class CloseListener : IListener
{
private Polling polling;
public CloseListener(Polling polling)
{
this.polling = polling;
}
public void Call(params object[] args)
{
//var log = LogManager.GetLogger(Global.CallerName());
//log.Info("writing close packet");
List<Packet> packets = new List<Packet>();
packets.Add(new Packet(Packet.CLOSE));
polling.Write(packets);
}
public int CompareTo(IListener other)
{
return this.GetId().CompareTo(other.GetId());
}
public int GetId()
{
return 0;
}
}
protected override void DoClose()
{
var log = LogManager.GetLogger(Global.CallerName());
var closeListener = new CloseListener(this);
if (ReadyState == ReadyStateEnum.OPEN)
{
log.Info("transport open - closing");
closeListener.Call();
}
else
{
// in case we're trying to close while
// handshaking is in progress (engine.io-client GH-164)
log.Info("transport not open - deferring close");
this.Once(EVENT_OPEN, closeListener);
}
}
public class SendEncodeCallback : IEncodeCallback
{
private Polling polling;
public SendEncodeCallback(Polling polling)
{
this.polling = polling;
}
public void Call(object data)
{
//var log = LogManager.GetLogger(Global.CallerName());
//log.Info("SendEncodeCallback data = " + data);
var byteData = (byte[]) data;
polling.DoWrite(byteData, () =>
{
polling.Writable = true;
polling.Emit(EVENT_DRAIN);
});
}
}
protected override void Write(List<Packet> packets)
{
var log = LogManager.GetLogger(Global.CallerName());
log.Info("Write packets.Count = " + packets.Count);
Writable = false;
var callback = new SendEncodeCallback(this);
Parser.Parser.EncodePayload(packets.ToArray(), callback);
}
public string Uri()
{
//var query = this.Query;
var query = new Dictionary<string, string>(Query);
//if (Query == null)
//{
// query = new Dictionary<string, string>();
//}
string schema = this.Secure ? "https" : "http";
string portString = "";
if (this.TimestampRequests)
{
query.Add(this.TimestampParam, DateTime.Now.Ticks + "-" + Transport.Timestamps++);
}
query.Add("b64", "1");
string _query = ParseQS.Encode(query);
if (this.Port > 0 && (("https" == schema && this.Port != 443)
|| ("http" == schema && this.Port != 80)))
{
portString = ":" + this.Port;
}
if (_query.Length > 0)
{
_query = "?" + _query;
}
return schema + "://" + this.Hostname + portString + this.Path + _query;
}
protected virtual void DoWrite(byte[] data, Action action)
{
}
protected virtual void DoPoll()
{
}
}
}

View File

@@ -0,0 +1,215 @@
using Quobject.EngineIoClientDotNet.Modules;
using Quobject.EngineIoClientDotNet.Parser;
using System;
using System.Net;
using System.Collections.Generic;
using WebSocket4Net;
using SuperSocket.ClientEngine.Proxy;
namespace Quobject.EngineIoClientDotNet.Client.Transports
{
public class WebSocket : Transport
{
public static readonly string NAME = "websocket";
private WebSocket4Net.WebSocket ws;
private List<KeyValuePair<string, string>> Cookies;
private List<KeyValuePair<string, string>> MyExtraHeaders;
public WebSocket(Options opts)
: base(opts)
{
Name = NAME;
Cookies = new List<KeyValuePair<string, string>>();
foreach (var cookie in opts.Cookies)
{
Cookies.Add(new KeyValuePair<string, string>(cookie.Key, cookie.Value));
}
MyExtraHeaders = new List<KeyValuePair<string, string>>();
foreach (var header in opts.ExtraHeaders)
{
MyExtraHeaders.Add(new KeyValuePair<string, string>(header.Key, header.Value));
}
}
protected override void DoOpen()
{
var log = LogManager.GetLogger(Global.CallerName());
log.Info("DoOpen uri =" + this.Uri());
ws = new WebSocket4Net.WebSocket(this.Uri(), String.Empty, Cookies, MyExtraHeaders)
{
EnableAutoSendPing = false
};
if (ServerCertificate.Ignore)
{
var security = ws.Security;
if (security != null)
{
security.AllowUnstrustedCertificate = true;
security.AllowNameMismatchCertificate = true;
}
}
ws.Opened += ws_Opened;
ws.Closed += ws_Closed;
ws.MessageReceived += ws_MessageReceived;
ws.DataReceived += ws_DataReceived;
ws.Error += ws_Error;
var destUrl = new UriBuilder(this.Uri());
if (this.Secure)
destUrl.Scheme = "https";
else
destUrl.Scheme = "http";
var useProxy = !WebRequest.DefaultWebProxy.IsBypassed(destUrl.Uri);
if (useProxy)
{
var proxyUrl = WebRequest.DefaultWebProxy.GetProxy(destUrl.Uri);
var proxy = new HttpConnectProxy(new DnsEndPoint(proxyUrl.Host, proxyUrl.Port), destUrl.Host);
ws.Proxy = proxy;
}
ws.Open();
}
void ws_DataReceived(object sender, DataReceivedEventArgs e)
{
var log = LogManager.GetLogger(Global.CallerName());
log.Info("ws_DataReceived " + e.Data);
this.OnData(e.Data);
}
private void ws_Opened(object sender, EventArgs e)
{
var log = LogManager.GetLogger(Global.CallerName());
log.Info("ws_Opened " + ws.SupportBinary);
this.OnOpen();
}
void ws_Closed(object sender, EventArgs e)
{
var log = LogManager.GetLogger(Global.CallerName());
log.Info("ws_Closed");
ws.Opened -= ws_Opened;
ws.Closed -= ws_Closed;
ws.MessageReceived -= ws_MessageReceived;
ws.DataReceived -= ws_DataReceived;
ws.Error -= ws_Error;
this.OnClose();
}
void ws_MessageReceived(object sender, MessageReceivedEventArgs e)
{
var log = LogManager.GetLogger(Global.CallerName());
log.Info("ws_MessageReceived e.Message= " + e.Message);
this.OnData(e.Message);
}
void ws_Error(object sender, SuperSocket.ClientEngine.ErrorEventArgs e)
{
this.OnError("websocket error", e.Exception);
}
protected override void Write(System.Collections.Immutable.ImmutableList<Parser.Packet> packets)
{
Writable = false;
foreach (var packet in packets)
{
Parser.Parser.EncodePacket(packet, new WriteEncodeCallback(this));
}
// fake drain
// defer to next tick to allow Socket to clear writeBuffer
//EasyTimer.SetTimeout(() =>
//{
Writable = true;
Emit(EVENT_DRAIN);
//}, 1);
}
public class WriteEncodeCallback : IEncodeCallback
{
private WebSocket webSocket;
public WriteEncodeCallback(WebSocket webSocket)
{
this.webSocket = webSocket;
}
public void Call(object data)
{
//var log = LogManager.GetLogger(Global.CallerName());
if (data is string)
{
webSocket.ws.Send((string)data);
}
else if (data is byte[])
{
var d = (byte[])data;
//try
//{
// var dataString = BitConverter.ToString(d);
// //log.Info(string.Format("WriteEncodeCallback byte[] data {0}", dataString));
//}
//catch (Exception e)
//{
// log.Error(e);
//}
webSocket.ws.Send(d, 0, d.Length);
}
}
}
protected override void DoClose()
{
if (ws != null)
{
try
{
ws.Close();
}
catch (Exception e)
{
var log = LogManager.GetLogger(Global.CallerName());
log.Info("DoClose ws.Close() Exception= " + e.Message);
}
}
}
public string Uri()
{
Dictionary<string, string> query = null;
query = this.Query == null ? new Dictionary<string, string>() : new Dictionary<string, string>(this.Query);
var schema = this.Secure ? "wss" : "ws";
var portString = "";
if (this.TimestampRequests)
{
query.Add(this.TimestampParam, DateTime.Now.Ticks.ToString() + "-" + Transport.Timestamps++);
}
var _query = ParseQS.Encode(query);
if (this.Port > 0 && (("wss" == schema && this.Port != 443)
|| ("ws" == schema && this.Port != 80)))
{
portString = ":" + this.Port;
}
if (_query.Length > 0)
{
_query = "?" + _query;
}
return schema + "://" + this.Hostname + portString + this.Path + _query;
}
}
}

View File

@@ -0,0 +1,197 @@
using System.Collections.Concurrent;
using System.Net;
using Quobject.EngineIoClientDotNet.Modules;
using Quobject.EngineIoClientDotNet.Parser;
using System;
using System.Collections.Generic;
using WebSocket4Net;
namespace Quobject.EngineIoClientDotNet.Client.Transports
{
public class WebSocket : Transport
{
public static readonly string NAME = "websocket";
private WebSocket4Net.WebSocket ws;
private List<KeyValuePair<string, string>> Cookies;
public WebSocket(Options opts)
: base(opts)
{
Name = NAME;
Cookies = new List<KeyValuePair<string, string>>();
foreach (var cookie in opts.Cookies)
{
Cookies.Add(new KeyValuePair<string, string>(cookie.Key,cookie.Value));
}
}
protected override void DoOpen()
{
var log = LogManager.GetLogger(Global.CallerName());
log.Info("DoOpen uri =" + this.Uri());
ws = new WebSocket4Net.WebSocket(this.Uri(),"",Cookies);
ws.EnableAutoSendPing = false;
if (ServerCertificate.Ignore)
{
var security = ws.Security;
if (security != null)
{
security.AllowUnstrustedCertificate = true;
security.AllowNameMismatchCertificate = true;
}
}
ws.Opened += ws_Opened;
ws.Closed += ws_Closed;
ws.MessageReceived += ws_MessageReceived;
ws.DataReceived += ws_DataReceived;
ws.Error += ws_Error;
ws.Open();
}
void ws_DataReceived(object sender, DataReceivedEventArgs e)
{
var log = LogManager.GetLogger(Global.CallerName());
log.Info("ws_DataReceived " + e.Data);
this.OnData(e.Data);
}
private void ws_Opened(object sender, EventArgs e)
{
var log = LogManager.GetLogger(Global.CallerName());
log.Info("ws_Opened " + ws.SupportBinary);
this.OnOpen();
}
void ws_Closed(object sender, EventArgs e)
{
var log = LogManager.GetLogger(Global.CallerName());
log.Info("ws_Closed");
ws.Opened -= ws_Opened;
ws.Closed -= ws_Closed;
ws.MessageReceived -= ws_MessageReceived;
ws.DataReceived -= ws_DataReceived;
ws.Error -= ws_Error;
this.OnClose();
}
void ws_MessageReceived(object sender, MessageReceivedEventArgs e)
{
var log = LogManager.GetLogger(Global.CallerName());
log.Info("ws_MessageReceived e.Message= " + e.Message);
this.OnData(e.Message);
}
void ws_Error(object sender, SuperSocket.ClientEngine.ErrorEventArgs e)
{
this.OnError("websocket error", e.Exception);
}
protected override void Write(List<Parser.Packet> packets)
{
Writable = false;
lock (packets)
{
foreach (var packet in packets)
{
Parser.Parser.EncodePacket(packet, new WriteEncodeCallback(this));
}
}
// fake drain
// defer to next tick to allow Socket to clear writeBuffer
//EasyTimer.SetTimeout(() =>
//{
Writable = true;
Emit(EVENT_DRAIN);
//}, 1);
}
public class WriteEncodeCallback : IEncodeCallback
{
private WebSocket webSocket;
public WriteEncodeCallback(WebSocket webSocket)
{
this.webSocket = webSocket;
}
public void Call(object data)
{
//var log = LogManager.GetLogger(Global.CallerName());
if (data is string)
{
webSocket.ws.Send((string)data);
}
else if (data is byte[])
{
var d = (byte[])data;
//try
//{
// var dataString = BitConverter.ToString(d);
// //log.Info(string.Format("WriteEncodeCallback byte[] data {0}", dataString));
//}
//catch (Exception e)
//{
// log.Error(e);
//}
webSocket.ws.Send(d, 0, d.Length);
}
}
}
protected override void DoClose()
{
if (ws != null)
{
try
{
ws.Close();
}
catch (Exception e)
{
var log = LogManager.GetLogger(Global.CallerName());
log.Info("DoClose ws.Close() Exception= " + e.Message);
}
}
}
public string Uri()
{
Dictionary<string, string> query = null;
query = this.Query == null ? new Dictionary<string, string>() : new Dictionary<string, string>(this.Query);
string schema = this.Secure ? "wss" : "ws";
string portString = "";
if (this.TimestampRequests)
{
query.Add(this.TimestampParam, DateTime.Now.Ticks.ToString() + "-" + Transport.Timestamps++);
}
string _query = ParseQS.Encode(query);
if (this.Port > 0 && (("wss" == schema && this.Port != 443)
|| ("ws" == schema && this.Port != 80)))
{
portString = ":" + this.Port;
}
if (_query.Length > 0)
{
_query = "?" + _query;
}
return schema + "://" + this.Hostname + portString + this.Path + _query;
}
}
}

View File

@@ -0,0 +1,215 @@
using Quobject.EngineIoClientDotNet.Modules;
using Quobject.EngineIoClientDotNet.Parser;
using System;
using System.Net;
using System.Collections.Generic;
using WebSocket4Net;
using SuperSocket.ClientEngine.Proxy;
namespace Quobject.EngineIoClientDotNet.Client.Transports
{
public class WebSocket : Transport
{
public static readonly string NAME = "websocket";
private WebSocket4Net.WebSocket ws;
private List<KeyValuePair<string, string>> Cookies;
private List<KeyValuePair<string, string>> MyExtraHeaders;
public WebSocket(Options opts)
: base(opts)
{
Name = NAME;
Cookies = new List<KeyValuePair<string, string>>();
foreach (var cookie in opts.Cookies)
{
Cookies.Add(new KeyValuePair<string, string>(cookie.Key, cookie.Value));
}
MyExtraHeaders = new List<KeyValuePair<string, string>>();
foreach (var header in opts.ExtraHeaders)
{
MyExtraHeaders.Add(new KeyValuePair<string, string>(header.Key, header.Value));
}
}
protected override void DoOpen()
{
var log = LogManager.GetLogger(Global.CallerName());
log.Info("DoOpen uri =" + this.Uri());
ws = new WebSocket4Net.WebSocket(this.Uri(), String.Empty, Cookies, MyExtraHeaders)
{
EnableAutoSendPing = false
};
if (ServerCertificate.Ignore)
{
var security = ws.Security;
if (security != null)
{
security.AllowUnstrustedCertificate = true;
security.AllowNameMismatchCertificate = true;
}
}
ws.Opened += ws_Opened;
ws.Closed += ws_Closed;
ws.MessageReceived += ws_MessageReceived;
ws.DataReceived += ws_DataReceived;
ws.Error += ws_Error;
var destUrl = new UriBuilder(this.Uri());
if (this.Secure)
destUrl.Scheme = "https";
else
destUrl.Scheme = "http";
var useProxy = !WebRequest.DefaultWebProxy.IsBypassed(destUrl.Uri);
if (useProxy)
{
var proxyUrl = WebRequest.DefaultWebProxy.GetProxy(destUrl.Uri);
var proxy = new HttpConnectProxy(new DnsEndPoint(proxyUrl.Host, proxyUrl.Port), destUrl.Host);
ws.Proxy = proxy;
}
ws.Open();
}
void ws_DataReceived(object sender, DataReceivedEventArgs e)
{
var log = LogManager.GetLogger(Global.CallerName());
log.Info("ws_DataReceived " + e.Data);
this.OnData(e.Data);
}
private void ws_Opened(object sender, EventArgs e)
{
var log = LogManager.GetLogger(Global.CallerName());
log.Info("ws_Opened " + ws.SupportBinary);
this.OnOpen();
}
void ws_Closed(object sender, EventArgs e)
{
var log = LogManager.GetLogger(Global.CallerName());
log.Info("ws_Closed");
ws.Opened -= ws_Opened;
ws.Closed -= ws_Closed;
ws.MessageReceived -= ws_MessageReceived;
ws.DataReceived -= ws_DataReceived;
ws.Error -= ws_Error;
this.OnClose();
}
void ws_MessageReceived(object sender, MessageReceivedEventArgs e)
{
var log = LogManager.GetLogger(Global.CallerName());
log.Info("ws_MessageReceived e.Message= " + e.Message);
this.OnData(e.Message);
}
void ws_Error(object sender, SuperSocket.ClientEngine.ErrorEventArgs e)
{
this.OnError("websocket error", e.Exception);
}
protected override void Write(System.Collections.Immutable.ImmutableList<Parser.Packet> packets)
{
Writable = false;
foreach (var packet in packets)
{
Parser.Parser.EncodePacket(packet, new WriteEncodeCallback(this));
}
// fake drain
// defer to next tick to allow Socket to clear writeBuffer
//EasyTimer.SetTimeout(() =>
//{
Writable = true;
Emit(EVENT_DRAIN);
//}, 1);
}
public class WriteEncodeCallback : IEncodeCallback
{
private WebSocket webSocket;
public WriteEncodeCallback(WebSocket webSocket)
{
this.webSocket = webSocket;
}
public void Call(object data)
{
//var log = LogManager.GetLogger(Global.CallerName());
if (data is string)
{
webSocket.ws.Send((string)data);
}
else if (data is byte[])
{
var d = (byte[])data;
//try
//{
// var dataString = BitConverter.ToString(d);
// //log.Info(string.Format("WriteEncodeCallback byte[] data {0}", dataString));
//}
//catch (Exception e)
//{
// log.Error(e);
//}
webSocket.ws.Send(d, 0, d.Length);
}
}
}
protected override void DoClose()
{
if (ws != null)
{
try
{
ws.Close();
}
catch (Exception e)
{
var log = LogManager.GetLogger(Global.CallerName());
log.Info("DoClose ws.Close() Exception= " + e.Message);
}
}
}
public string Uri()
{
Dictionary<string, string> query = null;
query = this.Query == null ? new Dictionary<string, string>() : new Dictionary<string, string>(this.Query);
var schema = this.Secure ? "wss" : "ws";
var portString = "";
if (this.TimestampRequests)
{
query.Add(this.TimestampParam, DateTime.Now.Ticks.ToString() + "-" + Transport.Timestamps++);
}
var _query = ParseQS.Encode(query);
if (this.Port > 0 && (("wss" == schema && this.Port != 443)
|| ("ws" == schema && this.Port != 80)))
{
portString = ":" + this.Port;
}
if (_query.Length > 0)
{
_query = "?" + _query;
}
return schema + "://" + this.Hostname + portString + this.Path + _query;
}
}
}