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,180 @@
using Quobject.EngineIoClientDotNet.Client;
using Quobject.EngineIoClientDotNet.Client.Transports;
using System.Collections.Concurrent;
using System.Collections.Immutable;
using System.Threading;
using Xunit;
namespace Quobject.EngineIoClientDotNet_Tests.ClientTests
{
public class BinaryPollingTest : Connection
{
//[Fact]
//public void PingTest()
//{
// var log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod());
// log.Info("Start");
// var binaryData = new byte[5];
// for (int i = 0; i < binaryData.Length; i++)
// {
// binaryData[i] = (byte)i;
// }
// var events = new ConcurrentQueue<object>();
// var options = CreateOptions();
// options.Transports = ImmutableList.Create<string>(Polling.NAME);
// var socket = new Socket(options);
// socket.On(Socket.EVENT_OPEN, () =>
// {
// log.Info("EVENT_OPEN");
// socket.Send(binaryData);
// socket.Send("cash money €€€");
// });
// socket.On(Socket.EVENT_MESSAGE, (d) =>
// {
// var data = d as string;
// log.Info(string.Format("EVENT_MESSAGE data ={0} d = {1} ", data, d));
// if (data == "hi")
// {
// return;
// }
// events.Enqueue(d);
// //socket.Close();
// });
// socket.Open();
// Task.Delay(20000).Wait();
// socket.Close();
// log.Info("ReceiveBinaryData end");
// var binaryData2 = new byte[5];
// for (int i = 0; i < binaryData2.Length; i++)
// {
// binaryData2[i] = (byte)(i + 1);
// }
// object result;
// events.TryDequeue(out result);
// Assert.Equal("1", "1");
//}
private ManualResetEvent _manualResetEvent = null;
[Fact]
public void ReceiveBinaryData()
{
_manualResetEvent = new ManualResetEvent(false);
var events = new ConcurrentQueue<object>();
var binaryData = new byte[5];
for (int i = 0; i < binaryData.Length; i++)
{
binaryData[i] = (byte)i;
}
var options = CreateOptions();
options.Transports = ImmutableList.Create<string>(Polling.NAME);
var socket = new Socket(options);
socket.On(Socket.EVENT_OPEN, () =>
{
socket.Send(binaryData);
//socket.Send("cash money €€€");
});
socket.On(Socket.EVENT_MESSAGE, (d) =>
{
var data = d as string;
//log.Info(string.Format("EVENT_MESSAGE data ={0} d = {1} ", data, d));
if (data == "hi")
{
return;
}
events.Enqueue(d);
_manualResetEvent.Set();
});
socket.Open();
_manualResetEvent.WaitOne();
socket.Close();
//log.Info("ReceiveBinaryData end");
var binaryData2 = new byte[5];
for (int i = 0; i < binaryData2.Length; i++)
{
binaryData2[i] = (byte)(i + 1);
}
object result;
events.TryDequeue(out result);
Assert.Equal(binaryData, result);
}
[Fact]
public void ReceiveBinaryDataAndMultibyteUTF8String()
{
_manualResetEvent = new ManualResetEvent(false);
var events = new ConcurrentQueue<object>();
var binaryData = new byte[5];
for (int i = 0; i < binaryData.Length; i++)
{
binaryData[i] = (byte)i;
}
const string stringData = "cash money €€€";
var options = CreateOptions();
options.Transports = ImmutableList.Create<string>(Polling.NAME);
var socket = new Socket(options);
socket.On(Socket.EVENT_OPEN, () =>
{
socket.On(Socket.EVENT_MESSAGE, (d) =>
{
var data = d as string;
//log.Info(string.Format("EVENT_MESSAGE data ={0} d = {1} ", data, d));
if (data == "hi")
{
return;
}
events.Enqueue(d);
if (events.Count > 1)
{
_manualResetEvent.Set();
}
});
socket.Send(binaryData);
socket.Send(stringData);
});
socket.Open();
_manualResetEvent.WaitOne();
socket.Close();
var binaryData2 = new byte[5];
for (int i = 0; i < binaryData2.Length; i++)
{
binaryData2[i] = (byte)(i + 1);
}
object result;
events.TryDequeue(out result);
Assert.Equal(binaryData, result);
events.TryDequeue(out result);
Assert.Equal(stringData, (string)result);
socket.Close();
}
}
}

View File

@@ -0,0 +1,132 @@
using Quobject.EngineIoClientDotNet.Client;
using System.Collections.Concurrent;
using System.Threading;
using Xunit;
namespace Quobject.EngineIoClientDotNet_Tests.ClientTests
{
public class BinaryWebSocketTest : Connection
{
private ManualResetEvent _manualResetEvent = null;
[Fact]
public void ReceiveBinaryData()
{
_manualResetEvent = new ManualResetEvent(false);
var events = new ConcurrentQueue<object>();
var binaryData = new byte[5];
for (int i = 0; i < binaryData.Length; i++)
{
binaryData[i] = (byte)(i + 0);
}
var options = CreateOptions();
var socket = new Socket(options);
socket.On(Socket.EVENT_OPEN, () =>
{
//log.Info(Socket.EVENT_OPEN);
});
socket.On(Socket.EVENT_UPGRADE, () =>
{
//log.Info(Socket.EVENT_UPGRADE);
socket.Send(binaryData);
});
socket.On(Socket.EVENT_MESSAGE, (d) =>
{
var data = d as string;
//log.Info(string.Format("EVENT_MESSAGE data ={0} d = {1} ", data, d));
if (data == "hi")
{
return;
}
events.Enqueue(d);
_manualResetEvent.Set();
});
socket.Open();
_manualResetEvent.WaitOne();
socket.Close();
//log.Info("ReceiveBinaryData end");
var binaryData2 = new byte[5];
for (int i = 0; i < binaryData2.Length; i++)
{
binaryData2[i] = (byte)(i + 1);
}
object result;
events.TryDequeue(out result);
Assert.Equal(binaryData, result);
}
[Fact]
public void ReceiveBinaryDataAndMultibyteUTF8String()
{
_manualResetEvent = new ManualResetEvent(false);
var events = new ConcurrentQueue<object>();
var binaryData = new byte[5];
for (int i = 0; i < binaryData.Length; i++)
{
binaryData[i] = (byte)i;
}
const string stringData = "Ä ä Ü ü ß";
var options = CreateOptions();
var socket = new Socket(options);
socket.On(Socket.EVENT_OPEN, () =>
{
});
socket.On(Socket.EVENT_UPGRADE, () =>
{
//log.Info(Socket.EVENT_UPGRADE);
socket.Send(binaryData);
socket.Send(stringData);
});
socket.On(Socket.EVENT_MESSAGE, (d) =>
{
var data = d as string;
//log.Info(string.Format("EVENT_MESSAGE data ={0} d = {1} ", data, d));
if (data == "hi")
{
return;
}
events.Enqueue(d);
if (events.Count > 1)
{
_manualResetEvent.Set();
}
});
socket.Open();
_manualResetEvent.WaitOne();
socket.Close();
var binaryData2 = new byte[5];
for (int i = 0; i < binaryData2.Length; i++)
{
binaryData2[i] = (byte)(i + 1);
}
object result;
events.TryDequeue(out result);
Assert.Equal(binaryData, result);
events.TryDequeue(out result);
Assert.Equal(stringData, (string)result);
//log.Info("ReceiveBinaryDataAndMultibyteUTF8String end");
}
}
}

View File

@@ -0,0 +1,38 @@
using Quobject.EngineIoClientDotNet.Client;
using Quobject.EngineIoClientDotNet.Modules;
namespace Quobject.EngineIoClientDotNet_Tests.ClientTests
{
public class Connection
{
static Connection()
{
LogManager.SetupLogManager();
}
protected static Socket.Options CreateOptions()
{
var options = new Socket.Options
{
Port = ConnectionConstants.PORT,
Hostname = ConnectionConstants.HOSTNAME
};
//log.Info("Please add to your hosts file: 127.0.0.1 " + options.Hostname);
return options;
}
protected static Socket.Options CreateOptionsSecure()
{
var options = new Socket.Options
{
Port = ConnectionConstants.SSL_PORT,
Hostname = ConnectionConstants.HOSTNAME,
//log.Info("Please add to your hosts file: 127.0.0.1 " + options.Hostname);
Secure = true,
IgnoreServerCertificateValidation = true
};
return options;
}
}
}

View File

@@ -0,0 +1,10 @@
namespace Quobject.EngineIoClientDotNet_Tests.ClientTests
{
public static class ConnectionConstants
{
public static int PORT = 80;
public static string HOSTNAME = "testme.quobject.com";
public static int SSL_PORT = 443;
public static readonly int TIMEOUT = 300000;
}
}

View File

@@ -0,0 +1,211 @@
using Quobject.EngineIoClientDotNet.Client;
using Quobject.EngineIoClientDotNet.Client.Transports;
using Quobject.EngineIoClientDotNet.ComponentEmitter;
using System.Collections.Immutable;
using System.Threading;
using System.Threading.Tasks;
using Xunit;
namespace Quobject.EngineIoClientDotNet_Tests.ClientTests
{
public class ConnectionTest : Connection
{
private ManualResetEvent _manualResetEvent = null;
private Socket socket;
public string Message;
[Fact]
public void ConnectToLocalhost()
{
_manualResetEvent = new ManualResetEvent(false);
socket = new Socket(CreateOptions());
socket.On(Socket.EVENT_OPEN, new TestListener());
socket.On(Socket.EVENT_MESSAGE, new MessageListener(socket, this));
socket.Open();
_manualResetEvent.WaitOne();
socket.Close();
Assert.Equal("hi", this.Message);
}
public class TestListener : IListener
{
public void Call(params object[] args)
{
//log.Info("open");
}
public int CompareTo(IListener other)
{
return this.GetId().CompareTo(other.GetId());
}
public int GetId()
{
return 0;
}
}
public class MessageListener : IListener
{
private Socket socket;
private ConnectionTest connectionTest;
public MessageListener(Socket socket)
{
this.socket = socket;
}
public MessageListener(Socket socket, ConnectionTest connectionTest)
{
this.socket = socket;
this.connectionTest = connectionTest;
}
public void Call(params object[] args)
{
//log.Info("message = " + args[0]);
connectionTest.Message = (string)args[0];
connectionTest._manualResetEvent.Set();
}
public int CompareTo(IListener other)
{
return this.GetId().CompareTo(other.GetId());
}
public int GetId()
{
return 0;
}
}
[Fact]
public void ConnectToLocalhost2()
{
_manualResetEvent = new ManualResetEvent(false);
this.Message = "";
var options = CreateOptions();
options.Transports = ImmutableList.Create<string>(Polling.NAME);
socket = new Socket(options);
//socket = new Socket(CreateOptions());
socket.On(Socket.EVENT_OPEN, () =>
{
//log.Info("open");
//socket.Send("test send");
});
socket.On(Socket.EVENT_MESSAGE, (d) =>
{
var data = (string)d;
//log.Info("message2 = " + data);
this.Message = data;
_manualResetEvent.Set();
});
socket.Open();
_manualResetEvent.WaitOne();
socket.Close();
Assert.Equal("hi", this.Message);
}
[Fact]
public void TestmultibyteUtf8StringsWithPolling()
{
_manualResetEvent = new ManualResetEvent(false);
const string SendMessage = "cash money €€€";
socket = new Socket(CreateOptions());
socket.On(Socket.EVENT_OPEN, () =>
{
//log.Info("open");
socket.Send(SendMessage);
});
socket.On(Socket.EVENT_MESSAGE, (d) =>
{
var data = (string)d;
//log.Info("TestMessage data = " + data);
if (data == "hi")
{
return;
}
this.Message = data;
_manualResetEvent.Set();
});
socket.Open();
_manualResetEvent.WaitOne();
socket.Close();
//log.Info("TestmultibyteUtf8StringsWithPolling this.Message = " + this.Message);
Assert.Equal(SendMessage, this.Message);
}
[Fact]
public void Testemoji()
{
_manualResetEvent = new ManualResetEvent(false);
const string SendMessage = "\uD800-\uDB7F\uDB80-\uDBFF\uDC00-\uDFFF\uE000-\uF8FF";
var options = CreateOptions();
socket = new Socket(options);
socket.On(Socket.EVENT_OPEN, () =>
{
//log.Info("open");
socket.Send(SendMessage);
});
socket.On(Socket.EVENT_MESSAGE, (d) =>
{
var data = (string)d;
//log.Info(Socket.EVENT_MESSAGE);
if (data == "hi")
{
return;
}
this.Message = data;
_manualResetEvent.Set();
});
socket.Open();
_manualResetEvent.WaitOne();
socket.Close();
Assert.True(SendMessage == this.Message);
}
[Fact]
public async Task NotSendPacketsIfSocketCloses()
{
var noPacket = true;
socket = new Socket(CreateOptions());
socket.On(Socket.EVENT_OPEN, () =>
{
noPacket = true;
});
socket.Open();
socket.On(Socket.EVENT_PACKET_CREATE, () =>
{
noPacket = false;
//log.Info("NotSendPacketsIfSocketCloses EVENT_PACKET_CREATE noPacket = " + noPacket);
});
socket.Close();
await Task.Delay(1000);
//log.Info("NotSendPacketsIfSocketCloses end noPacket = " + noPacket);
Assert.True(noPacket);
}
}
}

View File

@@ -0,0 +1,69 @@
using Newtonsoft.Json;
using Quobject.EngineIoClientDotNet.Client;
using Quobject.EngineIoClientDotNet.Modules;
using System.IO;
namespace Quobject.EngineIoClientDotNet_Tests.ClientTests
{
public class Connection
{
public static readonly int TIMEOUT = 300000;
static Connection()
{
LogManager.SetupLogManager();
}
protected Socket.Options CreateOptions()
{
var config = ConfigBase.Load();
var options = new Socket.Options();
options.Port = config.server.port;
options.Hostname = config.server.hostname;
//log.Info("Please add to your hosts file: 127.0.0.1 " + options.Hostname);
return options;
}
protected Socket.Options CreateOptionsSecure()
{
var config = ConfigBase.Load();
var options = new Socket.Options();
options.Port = config.server.ssl_port;
options.Hostname = config.server.hostname;
//log.Info("Please add to your hosts file: 127.0.0.1 " + options.Hostname);
options.Secure = true;
options.IgnoreServerCertificateValidation = true;
return options;
}
}
public class ConfigBase
{
public string version { get; set; }
public ConfigServer server { get; set; }
public static ConfigBase Load()
{
//var configString = File.ReadAllText("./../../../../grunt/config.json");
var configString = @"{""version"":""0.1.0.0"",""server"":{""port"":80,""ssl_port"":443,""hostname"":""192.168.178.59""},""win"":{""powershell"":""C:/WINDOWS/System32/WindowsPowerShell/v1.0/powershell.exe"",""msbuild"":""C:/Windows/Microsoft.NET/Framework/v4.0.30319/msbuild.exe"",""xunit_path"":""C:/vendors/xunit"",""nuget"":""C:/vendors/nuget/nuget.exe""},""linux"":{""msbuild"":""xbuild"",""xunit_path"":""/home/apollo/vendors/xunit""}}";
var config = JsonConvert.DeserializeObject<ConfigBase>(configString);
return config;
}
}
public class ConfigServer
{
public string hostname { get; set; }
public int port { get; set; }
public int ssl_port { get; set; }
}
}

View File

@@ -0,0 +1,26 @@
using Quobject.EngineIoClientDotNet.Client;
using Xunit;
namespace Quobject.EngineIoClientDotNet_Tests.ClientTests
{
public class HandshakeDataTests
{
[Fact]
public void Test()
{
var json = @"{
sid: 'nne323',
upgrades: ['u1','u2'],
pingInterval: 12,
pingTimeout: 23
}";
var handshakeData = new HandshakeData(json);
Assert.Equal("u1", handshakeData.Upgrades[0]);
Assert.Equal("u2", handshakeData.Upgrades[1]);
Assert.Equal(12, handshakeData.PingInterval);
Assert.Equal(23, handshakeData.PingTimeout);
}
}
}

View File

@@ -0,0 +1,267 @@
using Quobject.EngineIoClientDotNet.Client;
using Quobject.EngineIoClientDotNet.Client.Transports;
using Quobject.EngineIoClientDotNet.ComponentEmitter;
using System;
using System.Collections.Concurrent;
using System.IO;
using System.Threading;
using Xunit;
namespace Quobject.EngineIoClientDotNet_Tests.ClientTests
{
public class SSLServerConnectionTest : Connection
{
private ManualResetEvent _manualResetEvent = null;
[Fact]
public void OpenAndClose()
{
_manualResetEvent = new ManualResetEvent(false);
var events = new ConcurrentQueue<string>();
var socket = new Socket(CreateOptionsSecure());
Console.WriteLine(Directory.GetCurrentDirectory());
socket.On(Socket.EVENT_OPEN, () =>
{
Console.WriteLine("EVENT_OPEN");
events.Enqueue(Socket.EVENT_OPEN);
socket.Close();
});
socket.On(Socket.EVENT_CLOSE, () =>
{
Console.WriteLine("EVENT_CLOSE");
events.Enqueue(Socket.EVENT_CLOSE);
_manualResetEvent.Set();
});
socket.Open();
_manualResetEvent.WaitOne();
socket.Close();
string result;
events.TryDequeue(out result);
Assert.Equal(Socket.EVENT_OPEN, result);
events.TryDequeue(out result);
Assert.Equal(Socket.EVENT_CLOSE, result);
}
[Fact]
public void Messages()
{
_manualResetEvent = new ManualResetEvent(false);
var events = new ConcurrentQueue<string>();
var socket = new Socket(CreateOptionsSecure());
socket.On(Socket.EVENT_OPEN, () =>
{
socket.Send("hello");
});
socket.On(Socket.EVENT_MESSAGE, (d) =>
{
var data = (string)d;
//log.Info("EVENT_MESSAGE data = " + data);
events.Enqueue(data);
if (events.Count > 1)
{
_manualResetEvent.Set();
}
});
socket.Open();
_manualResetEvent.WaitOne();
socket.Close();
string result;
events.TryDequeue(out result);
Assert.Equal("hi", result);
events.TryDequeue(out result);
Assert.Equal("hello", result);
}
[Fact]
public void Handshake()
{
_manualResetEvent = new ManualResetEvent(false);
HandshakeData handshake_data = null;
var socket = new Socket(CreateOptionsSecure());
socket.On(Socket.EVENT_HANDSHAKE, (data) =>
{
//log.Info(Socket.EVENT_HANDSHAKE + string.Format(" data = {0}", data));
handshake_data = data as HandshakeData;
_manualResetEvent.Set();
});
socket.Open();
_manualResetEvent.WaitOne();
socket.Close();
Assert.NotNull(handshake_data);
Assert.NotNull(handshake_data.Upgrades);
Assert.True(handshake_data.Upgrades.Count > 0);
Assert.True(handshake_data.PingInterval > 0);
Assert.True(handshake_data.PingTimeout > 0);
}
public class TestHandshakeListener : IListener
{
public HandshakeData HandshakeData;
private SSLServerConnectionTest serverConnectionTest;
public TestHandshakeListener(SSLServerConnectionTest serverConnectionTest)
{
this.serverConnectionTest = serverConnectionTest;
}
public void Call(params object[] args)
{
//log.Info(string.Format("open args[0]={0} args.Length={1}", args[0], args.Length));
HandshakeData = args[0] as HandshakeData;
serverConnectionTest._manualResetEvent.Set();
}
public int CompareTo(IListener other)
{
return this.GetId().CompareTo(other.GetId());
}
public int GetId()
{
return 0;
}
}
[Fact]
public void Handshake2()
{
_manualResetEvent = new ManualResetEvent(false);
var socket = new Socket(CreateOptionsSecure());
var testListener = new TestHandshakeListener(this);
socket.On(Socket.EVENT_HANDSHAKE, testListener);
socket.Open();
_manualResetEvent.WaitOne();
socket.Close();
Assert.NotNull(testListener.HandshakeData);
Assert.NotNull(testListener.HandshakeData.Upgrades);
Assert.True(testListener.HandshakeData.Upgrades.Count > 0);
Assert.True(testListener.HandshakeData.PingInterval > 0);
Assert.True(testListener.HandshakeData.PingTimeout > 0);
}
[Fact]
public void Upgrade()
{
_manualResetEvent = new ManualResetEvent(false);
var events = new ConcurrentQueue<object>();
var socket = new Socket(CreateOptionsSecure());
socket.On(Socket.EVENT_UPGRADING, (data) =>
{
//log.Info(Socket.EVENT_UPGRADING + string.Format(" data = {0}", data));
events.Enqueue(data);
});
socket.On(Socket.EVENT_UPGRADE, (data) =>
{
//log.Info(Socket.EVENT_UPGRADE + string.Format(" data = {0}", data));
events.Enqueue(data);
_manualResetEvent.Set();
});
socket.Open();
_manualResetEvent.WaitOne();
object test = null;
events.TryDequeue(out test);
Assert.NotNull(test);
Assert.IsAssignableFrom<Transport>(test);
events.TryDequeue(out test);
Assert.NotNull(test);
Assert.IsAssignableFrom<Transport>(test);
}
[Fact]
public void RememberWebsocket()
{
_manualResetEvent = new ManualResetEvent(false);
var socket1 = new Socket(CreateOptionsSecure());
string socket1TransportName = null;
string socket2TransportName = null;
socket1.On(Socket.EVENT_OPEN, () =>
{
socket1TransportName = socket1.Transport.Name;
});
socket1.On(Socket.EVENT_UPGRADE, (data) =>
{
//log.Info(Socket.EVENT_UPGRADE + string.Format(" data = {0}", data));
var transport = (Transport)data;
socket1.Close();
if (WebSocket.NAME == transport.Name)
{
var options = CreateOptionsSecure();
options.RememberUpgrade = true;
var socket2 = new Socket(options);
socket2.Open();
socket2TransportName = socket2.Transport.Name;
socket2.Close();
_manualResetEvent.Set();
}
});
socket1.Open();
_manualResetEvent.WaitOne();
Assert.Equal(Polling.NAME, socket1TransportName);
Assert.Equal(WebSocket.NAME, socket2TransportName);
}
[Fact]
public void NotRememberWebsocket()
{
_manualResetEvent = new ManualResetEvent(false);
var socket1 = new Socket(CreateOptionsSecure());
string socket1TransportName = null;
string socket2TransportName = null;
socket1.On(Socket.EVENT_OPEN, () =>
{
socket1TransportName = socket1.Transport.Name;
});
socket1.On(Socket.EVENT_UPGRADE, (data) =>
{
//log.Info(Socket.EVENT_UPGRADE + string.Format(" data = {0}", data));
var transport = (Transport)data;
if (WebSocket.NAME == transport.Name)
{
socket1.Close();
var options = CreateOptionsSecure();
options.RememberUpgrade = false;
var socket2 = new Socket(options);
socket2.On(Socket.EVENT_OPEN, () =>
{
//log.Info("EVENT_OPEN socket 2");
socket2TransportName = socket2.Transport.Name;
socket2.Close();
_manualResetEvent.Set();
});
socket2.Open();
}
});
socket1.Open();
_manualResetEvent.WaitOne();
Assert.Equal(Polling.NAME, socket1TransportName);
Assert.Equal(Polling.NAME, socket2TransportName);
}
}
}

View File

@@ -0,0 +1,451 @@
using Quobject.EngineIoClientDotNet.Client;
using Quobject.EngineIoClientDotNet.Client.Transports;
using Quobject.EngineIoClientDotNet.ComponentEmitter;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Threading;
using Xunit;
namespace Quobject.EngineIoClientDotNet_Tests.ClientTests
{
public class ServerConnectionTest : Connection
{
private ManualResetEvent _manualResetEvent = null;
[Fact]
public void OpenAndClose()
{
_manualResetEvent = new ManualResetEvent(false);
var events = new ConcurrentQueue<string>();
var options = CreateOptions();
options.Query = new Dictionary<string, string>
{
{
"access_token", "akaka"
}
};
options.QueryString = "akka=ekek";
var socket = new Socket(options);
socket.On(Socket.EVENT_OPEN, () =>
{
events.Enqueue(Socket.EVENT_OPEN);
socket.Close();
});
socket.On(Socket.EVENT_CLOSE, () =>
{
//log.Info("EVENT_CLOSE");
events.Enqueue(Socket.EVENT_CLOSE);
_manualResetEvent.Set();
});
socket.Open();
_manualResetEvent.WaitOne();
socket.Close();
string result;
events.TryDequeue(out result);
Assert.Equal(Socket.EVENT_OPEN, result);
events.TryDequeue(out result);
Assert.Equal(Socket.EVENT_CLOSE, result);
}
[Fact]
public void Messages()
{
_manualResetEvent = new ManualResetEvent(false);
var events = new ConcurrentQueue<string>();
var socket = new Socket(CreateOptions());
socket.On(Socket.EVENT_OPEN, () =>
{
socket.Send("hello");
});
socket.On(Socket.EVENT_MESSAGE, (d) =>
{
var data = (string)d;
//log.Info("EVENT_MESSAGE data = " + data);
events.Enqueue(data);
if (events.Count > 1)
{
_manualResetEvent.Set();
}
});
socket.Open();
_manualResetEvent.WaitOne();
socket.Close();
string result;
events.TryDequeue(out result);
Assert.Equal("hi", result);
events.TryDequeue(out result);
Assert.Equal("hello", result);
}
[Fact]
public void Handshake()
{
_manualResetEvent = new ManualResetEvent(false);
HandshakeData handshake_data = null;
var socket = new Socket(CreateOptions());
socket.On(Socket.EVENT_HANDSHAKE, (data) =>
{
//log.Info(Socket.EVENT_HANDSHAKE + string.Format(" data = {0}", data));
handshake_data = data as HandshakeData;
_manualResetEvent.Set();
});
socket.Open();
_manualResetEvent.WaitOne();
socket.Close();
Assert.NotNull(handshake_data);
Assert.NotNull(handshake_data.Upgrades);
Assert.True(handshake_data.Upgrades.Count > 0);
Assert.True(handshake_data.PingInterval > 0);
Assert.True(handshake_data.PingTimeout > 0);
}
public class TestHandshakeListener : IListener
{
public HandshakeData HandshakeData;
private ServerConnectionTest serverConnectionTest;
public TestHandshakeListener(ServerConnectionTest serverConnectionTest)
{
this.serverConnectionTest = serverConnectionTest;
}
public void Call(params object[] args)
{
//log.Info(string.Format("open args[0]={0} args.Length={1}", args[0], args.Length));
HandshakeData = args[0] as HandshakeData;
serverConnectionTest._manualResetEvent.Set();
}
public int CompareTo(IListener other)
{
return this.GetId().CompareTo(other.GetId());
}
public int GetId()
{
return 0;
}
}
[Fact]
public void Handshake2()
{
_manualResetEvent = new ManualResetEvent(false);
var socket = new Socket(CreateOptions());
var testListener = new TestHandshakeListener(this);
socket.On(Socket.EVENT_HANDSHAKE, testListener);
socket.Open();
_manualResetEvent.WaitOne();
socket.Close();
Assert.NotNull(testListener.HandshakeData);
Assert.NotNull(testListener.HandshakeData.Upgrades);
Assert.True(testListener.HandshakeData.Upgrades.Count > 0);
Assert.True(testListener.HandshakeData.PingInterval > 0);
Assert.True(testListener.HandshakeData.PingTimeout > 0);
}
[Fact]
public void Upgrade()
{
_manualResetEvent = new ManualResetEvent(false);
var events = new ConcurrentQueue<object>();
var socket = new Socket(CreateOptions());
socket.On(Socket.EVENT_UPGRADING, (data) =>
{
//log.Info(Socket.EVENT_UPGRADING + string.Format(" data = {0}", data));
events.Enqueue(data);
});
socket.On(Socket.EVENT_UPGRADE, (data) =>
{
//log.Info(Socket.EVENT_UPGRADE + string.Format(" data = {0}", data));
events.Enqueue(data);
_manualResetEvent.Set();
});
socket.Open();
_manualResetEvent.WaitOne();
object test = null;
events.TryDequeue(out test);
Assert.NotNull(test);
Assert.IsAssignableFrom<Transport>(test);
events.TryDequeue(out test);
Assert.NotNull(test);
Assert.IsAssignableFrom<Transport>(test);
}
[Fact]
public void RememberWebsocket()
{
_manualResetEvent = new ManualResetEvent(false);
var socket1 = new Socket(CreateOptions());
string socket1TransportName = null;
string socket2TransportName = null;
socket1.On(Socket.EVENT_OPEN, () =>
{
socket1TransportName = socket1.Transport.Name;
});
socket1.On(Socket.EVENT_UPGRADE, (data) =>
{
//log.Info(Socket.EVENT_UPGRADE + string.Format(" data = {0}", data));
var transport = (Transport)data;
socket1.Close();
if (WebSocket.NAME == transport.Name)
{
var options = CreateOptions();
options.RememberUpgrade = true;
var socket2 = new Socket(options);
socket2.Open();
socket2TransportName = socket2.Transport.Name;
socket2.Close();
_manualResetEvent.Set();
}
});
socket1.Open();
_manualResetEvent.WaitOne();
Assert.Equal(Polling.NAME, socket1TransportName);
Assert.Equal(WebSocket.NAME, socket2TransportName);
}
[Fact]
public void NotRememberWebsocket()
{
_manualResetEvent = new ManualResetEvent(false);
var socket1 = new Socket(CreateOptions());
string socket1TransportName = null;
string socket2TransportName = null;
socket1.On(Socket.EVENT_OPEN, () =>
{
socket1TransportName = socket1.Transport.Name;
});
socket1.On(Socket.EVENT_UPGRADE, (data) =>
{
//log.Info(Socket.EVENT_UPGRADE + string.Format(" data = {0}", data));
var transport = (Transport)data;
if (WebSocket.NAME == transport.Name)
{
socket1.Close();
var options = CreateOptions();
options.RememberUpgrade = false;
var socket2 = new Socket(options);
socket2.On(Socket.EVENT_OPEN, () =>
{
//log.Info("EVENT_OPEN socket 2");
socket2TransportName = socket2.Transport.Name;
socket2.Close();
_manualResetEvent.Set();
});
socket2.Open();
}
});
socket1.Open();
_manualResetEvent.WaitOne();
Assert.Equal(Polling.NAME, socket1TransportName);
Assert.Equal(Polling.NAME, socket2TransportName);
}
//Fails in .netstandard1.3 for EngineIoClientDotNet 1.0.4
[Fact]
public void Cookie()
{
_manualResetEvent = new ManualResetEvent(false);
var events = new Queue<string>();
var options = CreateOptions();
options.Cookies.Add("foo", "bar");
var socket = new Socket(options);
socket.On(Socket.EVENT_OPEN, () =>
{
socket.Send("cookie");
});
socket.On(Socket.EVENT_MESSAGE, (d) =>
{
var data = (string)d;
//log.Info("EVENT_MESSAGE data = " + data);
events.Enqueue(data);
if (events.Count > 1)
{
_manualResetEvent.Set();
}
});
socket.Open();
_manualResetEvent.WaitOne();
socket.Close();
string result;
result = events.Dequeue();
Assert.Equal("hi", result);
result = events.Dequeue();
Assert.Equal("got cookie", result);
}
//Fails in .netstandard1.3 for EngineIoClientDotNet 1.0.4
[Fact]
public void UpgradeCookie()
{
_manualResetEvent = new ManualResetEvent(false);
var events = new Queue<object>();
var options = CreateOptions();
options.Cookies.Add("foo", "bar");
var socket = new Socket(options);
socket.On(Socket.EVENT_UPGRADING, (data) =>
{
//log.Info(Socket.EVENT_UPGRADING + string.Format(" data = {0}", data));
events.Enqueue(data);
});
socket.On(Socket.EVENT_UPGRADE, (data) =>
{
//log.Info(Socket.EVENT_UPGRADE + string.Format(" data = {0}", data));
events.Enqueue(data);
socket.Send("cookie");
});
socket.On(Socket.EVENT_MESSAGE, (d) =>
{
if (events.Count > 1)
{
var data = (string)d;
//log.Info("EVENT_MESSAGE data = " + data);
events.Enqueue(data);
_manualResetEvent.Set();
}
});
socket.Open();
_manualResetEvent.WaitOne();
object test = null;
test = events.Dequeue();
Assert.NotNull(test);
Assert.IsAssignableFrom<Transport>(test);
test = events.Dequeue();
Assert.NotNull(test);
Assert.IsAssignableFrom<Transport>(test);
test = events.Dequeue();
Assert.Equal("got cookie", test);
}
//[Fact]
//public void PrimusEndpoint()
//{
// var log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod());
// //log.Info("Start");
// _manualResetEvent = new ManualResetEvent(false);
// var events = new Queue<string>();
// var options = CreateOptions();
// options.Cookies.Add("foo", "bar");
// options.Hostname = "testme.quobject.com/";
// options.Path = "primus";
// var socket = new Socket(options);
// //var socket = new Socket("testme.quobject.com");
// socket.On(Socket.EVENT_OPEN, () =>
// {
// //log.Info("EVENT_OPEN");
// socket.Send("cookie");
// });
// socket.On(Socket.EVENT_MESSAGE, (d) =>
// {
// var data = (string)d;
// //log.Info("EVENT_MESSAGE data = " + data);
// events.Enqueue(data);
// if (events.Count > 1)
// {
// _manualResetEvent.Set();
// }
// });
// socket.Open();
// _manualResetEvent.WaitOne();
// socket.Close();
// string result;
// result = events.Dequeue();
// Assert.Equal("hi", result);
// result = events.Dequeue();
// Assert.Equal("got cookie", result);
//}
// [Fact]
//public void MessagesMulti()
//{
// //logManager.Enabled = true;
// var log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod());
// //log.Info("Start");
// _manualResetEvent = new ManualResetEvent(false);
// var events = new ConcurrentQueue<string>();
// int count = 200;
// var socket = new Socket(CreateOptions());
// socket.On(Socket.EVENT_OPEN, () =>
// {
// //log.Info("EVENT_OPEN");
// Task.Run(() =>
// {
// for (int i = 0; i < count; i++)
// {
// socket.Send("multi");
// Task.Delay(TimeSpan.FromSeconds(1)).Wait();
// }
// });
// });
// socket.On(Socket.EVENT_MESSAGE, (d) =>
// {
// var data = (string)d;
// //log.Info("EVENT_MESSAGE data = " + data);
// events.Enqueue(data);
// if (events.Count > count)
// {
// _manualResetEvent.Set();
// }
// });
// socket.Open();
// _manualResetEvent.WaitOne();
// socket.Close();
// string result;
// events.TryDequeue(out result);
// Assert.Equal("hi", result);
// events.TryDequeue(out result);
// Assert.Equal("multi", result);
//}
}
}

View File

@@ -0,0 +1,76 @@
using Quobject.EngineIoClientDotNet.Client;
using System.Collections.Immutable;
using System.Threading.Tasks;
using Xunit;
namespace Quobject.EngineIoClientDotNet_Tests.ClientTests
{
public class SocketTest : Connection
{
private Socket socket;
public string Message;
[Fact]
public void FilterUpgrades()
{
var options = CreateOptions();
options.Transports = ImmutableList<string>.Empty.Add("polling");
socket = new Socket(options);
var immutablelist = socket.FilterUpgrades(ImmutableList<string>.Empty.Add("polling").Add("websocket"));
Assert.Equal("polling", immutablelist[0]);
Assert.Equal(1, immutablelist.Count);
}
[Fact]
public async Task SocketClosing()
{
var closed = false;
var error = false;
var options = CreateOptions();
socket = new Socket("ws://0.0.0.0:8080", options);
socket.On(Socket.EVENT_OPEN, () =>
{
//socket.Send("test send");
});
socket.On(Socket.EVENT_CLOSE, () =>
{
//log.Info("EVENT_CLOSE = ");
closed = true;
});
socket.Once(Socket.EVENT_ERROR, () =>
{
//log.Info("EVENT_ERROR = ");
error = true;
});
socket.Open();
//System.Threading.Thread.Sleep(TimeSpan.FromSeconds(1));
await Task.Delay(1000);
Assert.True(closed);
Assert.True(error);
}
[Fact]
public void SocketOptionCookies()
{
var options = new Socket.Options();
options.Cookies.Add("foo", "bar");
Assert.Equal("foo=bar", options.GetCookiesAsString());
options.Cookies.Add("name2", "value2");
Assert.Equal("foo=bar; name2=value2", options.GetCookiesAsString());
}
[Fact]
public void DefaultProtocol()
{
var socket = new Socket("testme.quobject.com");
Assert.NotNull(socket);
}
}
}

View File

@@ -0,0 +1,170 @@
using Quobject.EngineIoClientDotNet.Client;
using Quobject.EngineIoClientDotNet.Client.Transports;
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using Xunit;
namespace Quobject.EngineIoClientDotNet_Tests.ClientTests
{
// NOTE: tests for the rememberUpgrade option are on ServerConnectionTest.
public class TransportTest : Connection
{
[Fact]
public void Constructors()
{
var socket = new Socket(CreateOptions());
socket.Open();
System.Threading.Thread.Sleep(TimeSpan.FromSeconds(3));
Assert.NotNull(socket.Transport);
socket.Close();
}
[Fact]
public void Uri()
{
var options = new Transport.Options
{
Path = "/engine.io",
Hostname = Connection.CreateOptions().Hostname,
Secure = false,
Query = new Dictionary<string, string> { { "sid", "test" } },
TimestampRequests = false
};
var polling = new Polling(options);
var expected = string.Format("http://{0}/engine.io?sid=test&b64=1", options.Hostname);
Assert.Contains(expected, polling.Uri());
}
[Fact]
public void UriWithDefaultPort()
{
var options = new Transport.Options
{
Path = "/engine.io",
Hostname = Connection.CreateOptions().Hostname,
Secure = false,
Query = new Dictionary<string, string> { { "sid", "test" } },
TimestampRequests = false,
Port = 80
};
var polling = new Polling(options);
//Assert.Contains("http://localhost/engine.io?sid=test&b64=1", polling.Uri());
var expected = string.Format("http://{0}/engine.io?sid=test&b64=1", options.Hostname);
Assert.Contains(expected, polling.Uri());
}
[Fact]
public void UriWithPort()
{
var options = new Transport.Options
{
Path = "/engine.io",
Hostname = Connection.CreateOptions().Hostname,
Secure = false,
Query = new Dictionary<string, string> { { "sid", "test" } },
TimestampRequests = false,
Port = 3000
};
var polling = new Polling(options);
//Assert.Contains("http://localhost:3000/engine.io?sid=test&b64=1", polling.Uri());
var expected = string.Format("http://{0}:{1}/engine.io?sid=test&b64=1", options.Hostname, options.Port);
Assert.Contains(expected, polling.Uri());
}
[Fact]
public void HttpsUriWithDefaultPort()
{
var options = new Transport.Options
{
Path = "/engine.io",
Hostname = Connection.CreateOptions().Hostname,
Secure = true,
Query = new Dictionary<string, string> { { "sid", "test" } },
TimestampRequests = false,
Port = 443
};
var polling = new Polling(options);
//Assert.Contains("https://localhost/engine.io?sid=test&b64=1", polling.Uri());
var expected = string.Format("https://{0}/engine.io?sid=test&b64=1", options.Hostname);
Assert.Contains(expected, polling.Uri());
}
[Fact]
public void TimestampedUri()
{
var options = new Transport.Options
{
Path = "/engine.io",
Hostname = "test",
Secure = false,
Query = new Dictionary<string, string> { { "sid", "test" } },
TimestampRequests = true,
TimestampParam = "t"
};
var polling = new Polling(options);
var pat = @"http://test/engine.io\?sid=test&(t=[0-9]+-[0-9]+)";
var r = new Regex(pat, RegexOptions.IgnoreCase);
var test = polling.Uri();
//log.Info(test);
var m = r.Match(test);
Assert.True(m.Success);
}
[Fact]
public void WsUri()
{
var options = new Transport.Options
{
Path = "/engine.io",
Hostname = "test",
Secure = false,
Query = new Dictionary<string, string> { { "transport", "websocket" } },
TimestampRequests = false
};
var ws = new WebSocket(options);
Assert.Contains("ws://test/engine.io?transport=websocket", ws.Uri());
}
[Fact]
public void WssUri()
{
var options = new Transport.Options
{
Path = "/engine.io",
Hostname = "test",
Secure = true,
Query = new Dictionary<string, string> { { "transport", "websocket" } },
TimestampRequests = false
};
var ws = new WebSocket(options);
Assert.Contains("wss://test/engine.io?transport=websocket", ws.Uri());
}
[Fact]
public void WsTimestampedUri()
{
var options = new Transport.Options
{
Path = "/engine.io",
Hostname = "test",
Secure = false,
Query = new Dictionary<string, string> { { "sid", "test" } },
TimestampRequests = true,
TimestampParam = "woot"
};
var ws = new WebSocket(options);
var pat = @"ws://test/engine.io\?sid=test&(woot=[0-9]+-[0-9]+)";
var r = new Regex(pat, RegexOptions.IgnoreCase);
var test = ws.Uri();
//log.Info(test);
var m = r.Match(test);
Assert.True(m.Success);
}
}
}

View File

@@ -0,0 +1,45 @@
using Quobject.EngineIoClientDotNet.Client;
using System;
using Xunit;
namespace Quobject.EngineIoClientDotNet_Tests.ClientTests
{
public class UsageTest : Connection
{
[Fact]
public void Usage1()
{
var options = CreateOptions();
var socket = new Socket(options);
//You can use `Socket` to connect:
//var socket = new Socket("ws://localhost");
socket.On(Socket.EVENT_OPEN, () =>
{
socket.Send("hi");
socket.Close();
});
socket.Open();
//System.Threading.Thread.Sleep(TimeSpan.FromSeconds(2));
}
[Fact]
public void Usage2()
{
var options = CreateOptions();
var socket = new Socket(options);
//Receiving data
//var socket = new Socket("ws://localhost:3000");
socket.On(Socket.EVENT_OPEN, () =>
{
socket.On(Socket.EVENT_MESSAGE, (data) => Console.WriteLine((string)data));
});
socket.Open();
System.Threading.Thread.Sleep(TimeSpan.FromSeconds(2));
socket.Close();
}
}
}

View File

@@ -0,0 +1,399 @@
using Quobject.EngineIoClientDotNet.ComponentEmitter;
using Quobject.EngineIoClientDotNet.Modules;
using System;
using System.Collections.Generic;
using System.Linq;
using Xunit;
namespace Quobject.EngineIoClientDotNet_Tests.ComponentEmitterTests
{
public class EmitterTests
{
public class TestListener1 : IListener
{
private readonly List<object> _calls;
public TestListener1(List<object> calls)
{
this._calls = calls;
}
public void Call(params object[] args)
{
_calls.Add("one");
_calls.Add(args[0]);
}
public int CompareTo(IListener other)
{
return this.GetId().CompareTo(other.GetId());
}
public int GetId()
{
return 0;
}
}
public class TestListener2 : IListener
{
private readonly List<object> _calls;
public TestListener2(List<object> calls)
{
this._calls = calls;
}
public void Call(params object[] args)
{
_calls.Add("two");
_calls.Add(args[0]);
}
public int CompareTo(IListener other)
{
return this.GetId().CompareTo(other.GetId());
}
public int GetId()
{
return 0;
}
}
[Fact]
public void On()
{
var emitter = new Emitter();
var calls = new List<object>();
var listener1 = new TestListener1(calls);
emitter.On("foo", listener1);
var listener2 = new TestListener2(calls);
emitter.On("foo", listener2);
emitter.Emit("foo", 1);
emitter.Emit("bar", 1);
emitter.Emit("foo", 2);
var expected = new Object[] {"one", 1, "two", 1, "one", 2, "two", 2};
Assert.Equal(expected, calls.ToArray());
}
[Fact]
public void Once()
{
var emitter = new Emitter();
var calls = new List<object>();
var listener1 = new TestListener1(calls);
emitter.Once("foo", listener1);
emitter.Emit("foo", 1);
emitter.Emit("foo", 2);
emitter.Emit("foo", 3);
emitter.Emit("bar", 1);
var expected = new Object[] {"one", 1};
Assert.Equal(expected, calls.ToArray());
}
public class TestListener3 : IListener
{
private readonly List<object> _calls;
public TestListener3(List<object> calls)
{
this._calls = calls;
}
public void Call(params object[] args)
{
_calls.Add("one");
}
public int CompareTo(IListener other)
{
return this.GetId().CompareTo(other.GetId());
}
public int GetId()
{
return 0;
}
}
public class TestListener4 : IListener
{
private readonly List<object> _calls;
public TestListener4(List<object> calls)
{
this._calls = calls;
}
public void Call(params object[] args)
{
_calls.Add("two");
}
public int CompareTo(IListener other)
{
return this.GetId().CompareTo(other.GetId());
}
public int GetId()
{
return 0;
}
}
[Fact]
public void Off()
{
var emitter = new Emitter();
var calls = new List<object>();
var listener3 = new TestListener3(calls);
emitter.On("foo", listener3);
var listener4 = new TestListener4(calls);
emitter.On("foo", listener4);
emitter.Off("foo", listener4);
emitter.Emit("foo");
var expected = new Object[] {"one"};
Assert.Equal(expected, calls.ToArray());
}
[Fact]
public void OffWithOnce()
{
var emitter = new Emitter();
var calls = new List<object>();
var listener3 = new TestListener3(calls);
emitter.Once("foo", listener3);
emitter.Off("foo", listener3);
emitter.Emit("foo");
var expected = new Object[] {};
Assert.Equal(expected, calls.ToArray());
}
public class TestListener5 : IListener
{
private readonly List<bool> _called;
public TestListener5(List<bool> called)
{
this._called = called;
}
public void Call(params object[] args)
{
this._called[0] = true;
}
public int CompareTo(IListener other)
{
return this.GetId().CompareTo(other.GetId());
}
public int GetId()
{
return 0;
}
}
public class TestListener6 : IListener
{
private readonly Emitter _emitter;
private readonly IListener _bListener;
public TestListener6(Emitter emitter, IListener bListener)
{
this._emitter = emitter;
this._bListener = bListener;
}
public void Call(params object[] args)
{
_emitter.Off("tobi", _bListener);
}
public int CompareTo(IListener other)
{
return this.GetId().CompareTo(other.GetId());
}
public int GetId()
{
return 0;
}
}
[Fact]
public void OffWhenCalledfromEvent()
{
var emitter = new Emitter();
var called = new List<bool> {false};
var listener5 = new TestListener5(called);
var listener6 = new TestListener6(emitter, listener5);
emitter.On("tobi", listener6);
emitter.Once("tobi", listener5);
emitter.Emit("tobi");
Assert.True(called[0]);
called[0] = false;
emitter.Emit("tobi");
Assert.False(called[0]);
}
[Fact]
public void OffEvent()
{
var emitter = new Emitter();
var calls = new List<object>();
var listener3 = new TestListener3(calls);
emitter.On("foo", listener3);
var listener4 = new TestListener4(calls);
emitter.On("foo", listener3);
emitter.On("foo", listener4);
emitter.Off("foo");
emitter.Emit("foo");
emitter.Emit("foo");
var expected = new Object[] {};
Assert.Equal(expected, calls.ToArray());
}
[Fact]
public void OffAll()
{
var emitter = new Emitter();
var calls = new List<object>();
var listener3 = new TestListener3(calls);
var listener4 = new TestListener4(calls);
emitter.On("foo", listener3);
emitter.On("bar", listener4);
emitter.Emit("foo");
emitter.Emit("bar");
emitter.Off();
emitter.Emit("foo");
emitter.Emit("bar");
var expected = new Object[] {"one", "two"};
Assert.Equal(expected, calls.ToArray());
}
[Fact]
public void Listeners()
{
var emitter = new Emitter();
var calls = new List<object>();
var listener3 = new TestListener3(calls);
emitter.On("foo", listener3);
var expected = new IListener[] {listener3};
Assert.Equal(expected, emitter.Listeners("foo").ToArray());
}
[Fact]
public void ListenersWithoutHandlers()
{
var emitter = new Emitter();
var expected = new IListener[] {};
Assert.Equal(expected, emitter.Listeners("foo").ToArray());
}
[Fact]
public void HasListeners()
{
var emitter = new Emitter();
var calls = new List<object>();
Assert.False(emitter.HasListeners("foo"));
var listener3 = new TestListener3(calls);
emitter.On("foo", listener3);
Assert.True(emitter.HasListeners("foo"));
}
[Fact]
public void HasListenersWithoutHandlers()
{
var emitter = new Emitter();
Assert.False(emitter.HasListeners("foo"));
}
}
}

View File

@@ -0,0 +1,115 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{382C2A10-8043-49C6-9DE5-39CA25C2418C}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>EngineIoClientDotNet.Tests</RootNamespace>
<AssemblyName>EngineIoClientDotNet.Tests.mono</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\EngineIoClientDotNet.mono\packages\Newtonsoft.Json.10.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="SuperSocket.ClientEngine, Version=0.8.0.8, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\EngineIoClientDotNet.mono\packages\SuperSocket.ClientEngine.Core.0.8.0.8\lib\net45\SuperSocket.ClientEngine.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.ComponentModel.Composition" />
<Reference Include="System.Core" />
<Reference Include="System.IO.Compression" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Numerics" />
<Reference Include="System.Runtime.InteropServices.RuntimeInformation, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\EngineIoClientDotNet.mono\packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Web.Extensions" />
<Reference Include="System.Xml" />
<Reference Include="System.Xml.Linq" />
<Reference Include="WebSocket4Net, Version=0.15.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\EngineIoClientDotNet.mono\packages\WebSocket4Net.0.15.0-beta6\lib\net45\WebSocket4Net.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="xunit.abstractions, Version=2.0.0.0, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL">
<HintPath>..\EngineIoClientDotNet.mono\packages\xunit.abstractions.2.0.1\lib\net35\xunit.abstractions.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="xunit.assert, Version=2.2.0.3545, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL">
<HintPath>..\EngineIoClientDotNet.mono\packages\xunit.assert.2.2.0\lib\netstandard1.1\xunit.assert.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="xunit.core, Version=2.2.0.3545, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL">
<HintPath>..\EngineIoClientDotNet.mono\packages\xunit.extensibility.core.2.2.0\lib\netstandard1.1\xunit.core.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="xunit.execution.dotnet, Version=2.2.0.3545, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL">
<HintPath>..\EngineIoClientDotNet.mono\packages\xunit.extensibility.execution.2.2.0\lib\netstandard1.1\xunit.execution.dotnet.dll</HintPath>
<Private>True</Private>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="ClientTests\BinaryPollingTest.cs" />
<Compile Include="ClientTests\BinaryWebSocketTest.cs" />
<Compile Include="ClientTests\Connection.cs" />
<Compile Include="ClientTests\ConnectionTest.cs" />
<Compile Include="ClientTests\HandshakeDataTests.cs" />
<Compile Include="ClientTests\ServerConnectionTest.cs" />
<Compile Include="ClientTests\SocketTest.cs" />
<Compile Include="ClientTests\SSLServerConnectionTest.cs" />
<Compile Include="ClientTests\TransportTest.cs" />
<Compile Include="ClientTests\UsageTest.cs" />
<Compile Include="ComponentEmitterTests\EmitterTests.cs" />
<Compile Include="ModulesTests\ParseQSTests.cs" />
<Compile Include="ModulesTests\UTF8Tests.cs" />
<Compile Include="ParserTests\DecodeTests.cs" />
<Compile Include="ParserTests\TestsParser.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<Folder Include="ThreadTests\" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\EngineIoClientDotNet.mono\EngineIoClientDotNet.mono.csproj">
<Project>{b6731266-b247-4a63-b10b-f938288248b6}</Project>
<Name>EngineIoClientDotNet.mono</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@@ -0,0 +1,52 @@
using System.Collections.Immutable;
using Quobject.EngineIoClientDotNet.Modules;
using System.Collections.Generic;
using Xunit;
namespace Quobject.EngineIoClientDotNet_Tests.ModulesTests
{
public class ParseQsTests
{
//should parse a querystring and return an object
[Fact]
public void Decode()
{
// Single assignment
var queryObj = ParseQS.Decode("foo=bar");
Assert.Equal("bar", queryObj["foo"]);
// Multiple assignments
queryObj = ParseQS.Decode("france=grenoble&germany=mannheim");
Assert.Equal("grenoble", queryObj["france"]);
Assert.Equal("mannheim", queryObj["germany"]);
// Assignments containing non-alphanumeric characters
queryObj = ParseQS.Decode("india=new%20delhi");
Assert.Equal("new delhi", queryObj["india"]);
}
//should construct a query string from an object'
[Fact]
public void Encode()
{
Dictionary<string, string> obj;
obj = new Dictionary<string, string> {{"a", "b"}};
var imObj = ImmutableDictionary.Create<string, string>().AddRange(obj);
Assert.Equal("a=b", ParseQS.Encode(imObj));
obj = new Dictionary<string, string> {{"a", "b"}, {"c", "d"}};
imObj = ImmutableDictionary.Create<string, string>().AddRange(obj);
Assert.Equal("a=b&c=d", ParseQS.Encode(imObj));
obj = new Dictionary<string, string> {{"a", "b"}, {"c", "tobi rocks"}};
imObj = ImmutableDictionary.Create<string, string>().AddRange(obj);
Assert.Equal("a=b&c=tobi%20rocks", ParseQS.Encode(imObj));
}
}
}

View File

@@ -0,0 +1,140 @@
using Quobject.EngineIoClientDotNet.Modules;
using System;
using Xunit;
namespace Quobject.EngineIoClientDotNet_Tests.ModulesTests
{
public class Utf8Tests
{
private static readonly Data[] DATA = new Data[]
{
// 1-byte
new Data(0x0000, "\x00", "\x00"),
new Data(0x005c, "\u005C\u005C", "\u005C\u005C"), // = backslash
new Data(0x007f, "\u007F", "\u007F"),
// 2-byte
new Data(0x0080, "\u0080", "\u00C2\u0080"),
new Data(0x05CA, "\u05CA", "\u00D7\u008A"),
new Data(0x07FF, "\u07FF", "\u00DF\u00BF"),
// 3-byte
new Data(0x0800, "\u0800", "\u00E0\u00A0\u0080"),
new Data(0x2C3C, "\u2C3C", "\u00E2\u00B0\u00BC"),
new Data(0x07FF, "\uFFFF", "\u00EF\u00BF\u00BF"),
// unmatched surrogate halves
// high surrogates: 0xD800 to 0xDBFF
new Data(0xD800, "\uD800", "\u00ED\u00A0\u0080"),
new Data("High surrogate followed by another high surrogate",
"\uD800\uD800", "\u00ED\u00A0\u0080\u00ED\u00A0\u0080"),
new Data("High surrogate followed by a symbol that is not a surrogate",
"\uD800A", "\u00ED\u00A0\u0080A"),
new Data(
"Unmatched high surrogate, followed by a surrogate pair, followed by an unmatched high surrogate",
"\uD800\uD834\uDF06\uD800", "\u00ED\u00A0\u0080\u00F0\u009D\u008C\u0086\u00ED\u00A0\u0080"),
new Data(0xD9AF, "\uD9AF", "\u00ED\u00A6\u00AF"),
new Data(0xDBFF, "\uDBFF", "\u00ED\u00AF\u00BF"),
// low surrogates: 0xDC00 to 0xDFFF
new Data(0xDC00, "\uDC00", "\u00ED\u00B0\u0080"),
new Data("Low surrogate followed by another low surrogate",
"\uDC00\uDC00", "\u00ED\u00B0\u0080\u00ED\u00B0\u0080"),
new Data("Low surrogate followed by a symbol that is not a surrogate",
"\uDC00A", "\u00ED\u00B0\u0080A"),
new Data(
"Unmatched low surrogate, followed by a surrogate pair, followed by an unmatched low surrogate",
"\uDC00\uD834\uDF06\uDC00", "\u00ED\u00B0\u0080\u00F0\u009D\u008C\u0086\u00ED\u00B0\u0080"),
new Data(0xDEEE, "\uDEEE", "\u00ED\u00BB\u00AE"),
new Data(0xDFFF, "\uDFFF", "\u00ED\u00BF\u00BF"),
// 4-byte
new Data(0x010000, "\uD800\uDC00", "\u00F0\u0090\u0080\u0080"),
new Data(0x01D306, "\uD834\uDF06", "\u00F0\u009D\u008C\u0086"),
new Data(0x010FFF, "\uDBFF\uDFFF", "\u00F4\u008F\u00BF\u00BF"),
};
//
[Fact]
public void EncodeAndDecode()
{
foreach (var data in DATA)
{
data.Test();
}
}
private class Data
{
private readonly int _codePoint = -1;
private String Description { get; set; }
private String Decoded { get; set; }
private String Encoded { get; set; }
public Data(int codePoint, String decoded, String encoded)
{
this._codePoint = codePoint;
this.Decoded = decoded;
this.Encoded = encoded;
}
public Data(String description, String decoded, String encoded)
{
this.Description = description;
this.Decoded = decoded;
this.Encoded = encoded;
}
public void Test()
{
EncodingTest();
DecodingTest();
ExceptionTest();
}
private void EncodingTest()
{
var value = UTF8.Encode(Decoded);
Assert.Equal(Encoded, value);
}
private void DecodingTest()
{
Assert.Equal(Decoded, UTF8.Decode(Encoded));
}
private void ExceptionTest()
{
Assert.Throws<UTF8Exception>(
delegate
{
UTF8.Decode("\uFFFF");
});
Assert.Throws<UTF8Exception>(
delegate
{
UTF8.Decode("\xE9\x00\x00");
});
Assert.Throws<UTF8Exception>(
delegate
{
UTF8.Decode("\xC2\uFFFF");
});
Assert.Throws<UTF8Exception>(
delegate
{
UTF8.Decode("\xF0\x9D");
});
}
private string Reason
{
get { return Description ?? "U+" + _codePoint.ToString("X4").ToUpper(); }
}
}
}
}

View File

@@ -0,0 +1,82 @@
using Quobject.EngineIoClientDotNet.Modules;
using Quobject.EngineIoClientDotNet.Parser;
using Xunit;
namespace Quobject.EngineIoClientDotNet_Tests.ParserTests
{
public class DecodeTests
{
private const string PARSER_ERROR = "parser error";
[Fact]
public void DecodeBadFormat()
{
LogManager.SetupLogManager();
var log = LogManager.GetLogger("DecodeTests DecodeBadFormat");
Packet p = Parser.DecodePacket(":::");
Assert.Equal(Packet.ERROR, p.Type);
Assert.Equal(PARSER_ERROR, p.Data);
}
[Fact]
public void DecodeInexistingTypes()
{
Packet p = Parser.DecodePacket("94103");
Assert.Equal(Packet.ERROR, p.Type);
Assert.Equal(PARSER_ERROR, p.Data);
}
[Fact]
public void DecodeInvalidUTF8()
{
Packet p = Parser.DecodePacket("4\uffff", true);
Assert.Equal(Packet.ERROR, p.Type);
Assert.Equal(PARSER_ERROR, p.Data);
}
public class DecodePayloadBadFormat_DecodeCallback : IDecodePayloadCallback
{
public bool Call(Packet packet, int index, int total)
{
var isLast = index + 1 == total;
Assert.True(isLast);
Assert.Equal(Packet.ERROR, packet.Type);
Assert.Equal(PARSER_ERROR, packet.Data);
return true;
}
}
[Fact]
public void EncodeAndDecodeEmptyPayloads()
{
Packet.DecodePayload("1!", new DecodePayloadBadFormat_DecodeCallback());
Packet.DecodePayload("", new DecodePayloadBadFormat_DecodeCallback());
Packet.DecodePayload("))", new DecodePayloadBadFormat_DecodeCallback());
}
[Fact]
public void DecodePayloadBadPacketFormat()
{
Packet.DecodePayload("3:99", new DecodePayloadBadFormat_DecodeCallback());
Packet.DecodePayload("1:aa", new DecodePayloadBadFormat_DecodeCallback());
Packet.DecodePayload("1:a2:b", new DecodePayloadBadFormat_DecodeCallback());
}
[Fact]
public void DecodePayloadInvalidUTF8()
{
Packet.DecodePayload("2:4\uffff", new DecodePayloadBadFormat_DecodeCallback());
}
}
}

View File

@@ -0,0 +1,449 @@
using Quobject.EngineIoClientDotNet.Modules;
using Quobject.EngineIoClientDotNet.Parser;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using Xunit;
namespace Quobject.EngineIoClientDotNet_Tests.ParserTests
{
public class TestsParser
{
public interface IPacketTest
{
Packet GetPacket();
}
[Fact]
public void EncodeTests()
{
var testList = new List<IPacketTest>()
{
new EncodeAsStringCallback(),
new DecodeAsPacketCallback(),
new NoDataCallback(),
new EncodeOpenPacket(),
new EncodeClosePacket(),
new EncodePingPacket(),
new EncodePongPacket(),
new EncodeMessagePacket(),
new EncodeUTF8SpecialCharsPacket(),
new EncodeUpgradePacket(),
new EncodeFormat1(),
new EncodeFormat2(),
};
foreach (var test in testList)
{
Parser.EncodePacket(test.GetPacket(), (IEncodeCallback) test);
}
}
public class EncodeAsStringCallback : IEncodeCallback, IPacketTest
{
public void Call(object data)
{
Assert.IsType<string>(data);
}
public Packet GetPacket()
{
return new Packet(Packet.MESSAGE, "test");
}
}
public class DecodeAsPacketCallback : IEncodeCallback, IPacketTest
{
public void Call(object data)
{
Assert.IsType<Packet>(Parser.DecodePacket((string) data));
}
public Packet GetPacket()
{
return new Packet(Packet.MESSAGE, "test");
}
}
public class NoDataCallback : IEncodeCallback, IPacketTest
{
public void Call(object data)
{
Packet p = Parser.DecodePacket((string) data);
Assert.Equal(Packet.MESSAGE, p.Type);
Assert.Null(p.Data);
}
public Packet GetPacket()
{
return new Packet(Packet.MESSAGE);
}
}
public class EncodeOpenPacket : IEncodeCallback, IPacketTest
{
private static string Json = "{\"some\":\"json\"}";
public void Call(object data)
{
Packet p = Parser.DecodePacket((string) data);
Assert.Equal(Packet.OPEN, p.Type);
Assert.Equal(Json, p.Data);
}
public Packet GetPacket()
{
return new Packet(Packet.OPEN, Json);
}
}
public class EncodeClosePacket : IEncodeCallback, IPacketTest
{
public void Call(object data)
{
Packet p = Parser.DecodePacket((string) data);
Assert.Equal(Packet.CLOSE, p.Type);
}
public Packet GetPacket()
{
return new Packet(Packet.CLOSE);
}
}
public class EncodePingPacket : IEncodeCallback, IPacketTest
{
public void Call(object data)
{
Packet p = Parser.DecodePacket((string) data);
Assert.Equal(Packet.PING, p.Type);
Assert.Equal("1", p.Data);
}
public Packet GetPacket()
{
return new Packet(Packet.PING, "1");
}
}
public class EncodePongPacket : IEncodeCallback, IPacketTest
{
public void Call(object data)
{
Packet p = Parser.DecodePacket((string) data);
Assert.Equal(Packet.PONG, p.Type);
Assert.Equal("1", p.Data);
}
public Packet GetPacket()
{
return new Packet(Packet.PONG, "1");
}
}
public class EncodeMessagePacket : IEncodeCallback, IPacketTest
{
public void Call(object data)
{
Packet p = Parser.DecodePacket((string) data);
Assert.Equal(Packet.MESSAGE, p.Type);
Assert.Equal("aaa", p.Data);
}
public Packet GetPacket()
{
return new Packet(Packet.MESSAGE, "aaa");
}
}
public class EncodeUTF8SpecialCharsPacket : IEncodeCallback, IPacketTest
{
public void Call(object data)
{
Packet p = Parser.DecodePacket((string) data);
Assert.Equal(Packet.MESSAGE, p.Type);
Assert.Equal("utf8 — string", p.Data);
}
public Packet GetPacket()
{
return new Packet(Packet.MESSAGE, "utf8 — string");
}
}
public class EncodeUpgradePacket : IEncodeCallback, IPacketTest
{
public void Call(object data)
{
Packet p = Parser.DecodePacket((string) data);
Assert.Equal(Packet.UPGRADE, p.Type);
}
public Packet GetPacket()
{
return new Packet(Packet.UPGRADE);
}
}
public class EncodeFormat1 : IEncodeCallback, IPacketTest
{
public void Call(object data)
{
var dataString = data as string;
var r = new Regex(@"[0-9]", RegexOptions.IgnoreCase);
Assert.True(r.Match(dataString).Success);
}
public Packet GetPacket()
{
return new Packet(Packet.MESSAGE);
}
}
public class EncodeFormat2 : IEncodeCallback, IPacketTest
{
public void Call(object data)
{
var dataString = data as string;
Assert.Equal("4test", dataString);
}
public Packet GetPacket()
{
return new Packet(Packet.MESSAGE, "test");
}
}
public class EncodePayloadsCallback : IEncodeCallback
{
public void Call(object data)
{
Assert.IsType<byte[]>(data);
}
}
[Fact]
public void EncodePayloads()
{
var packets = new Packet[] {new Packet(Packet.PING), new Packet(Packet.PONG),};
Parser.EncodePayload(packets, new EncodePayloadsCallback());
}
public class EncodeAndDecodePayloads_EncodeCallback : IEncodeCallback
{
public void Call(object data)
{
Parser.DecodePayload((byte[]) data, new EncodeAndDecodePayloads_DecodeCallback());
}
public class EncodeAndDecodePayloads_DecodeCallback : IDecodePayloadCallback
{
public bool Call(Packet packet, int index, int total)
{
bool isLast = index + 1 == total;
Assert.True(isLast);
return true;
}
}
}
[Fact]
public void EncodeAndDecodePayloads()
{
var packets = new Packet[] {new Packet(Packet.MESSAGE, "a"),};
Parser.EncodePayload(packets, new EncodeAndDecodePayloads_EncodeCallback());
}
public class EncodeAndDecodePayloads_EncodeCallback2 : IEncodeCallback
{
public void Call(object data)
{
Parser.DecodePayload((byte[]) data, new EncodeAndDecodePayloads_DecodeCallback2());
}
public class EncodeAndDecodePayloads_DecodeCallback2 : IDecodePayloadCallback
{
public bool Call(Packet packet, int index, int total)
{
var isLast = index + 1 == total;
Assert.Equal(isLast ? Packet.PING : Packet.MESSAGE, packet.Type);
return true;
}
}
}
[Fact]
public void EncodeAndDecodePayloads2()
{
var packets = new Packet[] {new Packet(Packet.MESSAGE, "a"), new Packet(Packet.PING),};
Parser.EncodePayload(packets, new EncodeAndDecodePayloads_EncodeCallback2());
}
public class EncodeAndDecodeEmptyPayloads_EncodeCallback : IEncodeCallback
{
public void Call(object data)
{
Parser.DecodePayload((byte[]) data, new EncodeAndDecodeEmptyPayloads_DecodeCallback());
}
public class EncodeAndDecodeEmptyPayloads_DecodeCallback : IDecodePayloadCallback
{
public bool Call(Packet packet, int index, int total)
{
Assert.Equal(Packet.OPEN, packet.Type);
var isLast = index + 2 == total;
Assert.True(isLast);
return true;
}
}
}
[Fact]
public void EncodeAndDecodeEmptyPayloads()
{
var packets = new Packet[] {};
Parser.EncodePayload(packets, new EncodeAndDecodeEmptyPayloads_EncodeCallback());
}
public class EncodeAndDecodeBinaryContents_EncodeCallback : IEncodeCallback
{
public void Call(object data)
{
Parser.DecodePayload((byte[]) data, new EncodeAndDecodeBinaryContents_DecodeCallback());
}
public class EncodeAndDecodeBinaryContents_DecodeCallback : IDecodePayloadCallback
{
public bool Call(Packet packet, int index, int total)
{
Assert.Equal(Packet.MESSAGE, packet.Type);
var isLast = index + 1 == total;
if (!isLast)
{
Assert.Equal(FirstBuffer(), packet.Data);
}
else
{
Assert.Equal(SecondBuffer(), packet.Data);
}
return true;
}
}
}
[Fact]
public void EncodeAndDecodeBinaryContents()
{
var firstBuffer = FirstBuffer();
var secondBuffer = SecondBuffer();
var packets = new Packet[]
{new Packet(Packet.MESSAGE, firstBuffer), new Packet(Packet.MESSAGE, secondBuffer)};
Parser.EncodePayload(packets, new EncodeAndDecodeBinaryContents_EncodeCallback());
}
private static byte[] SecondBuffer()
{
var secondBuffer = new byte[4];
for (int i = 0; i < secondBuffer.Length; i++)
{
secondBuffer[i] = (byte) (5 + i);
}
return secondBuffer;
}
private static byte[] FirstBuffer()
{
var firstBuffer = new byte[5];
for (int i = 0; i < firstBuffer.Length; i++)
{
firstBuffer[i] = (byte) i;
}
return firstBuffer;
}
private static byte[] ThirdBuffer()
{
var result = new byte[123];
for (int i = 0; i < result.Length; i++)
{
result[i] = (byte) i;
}
return result;
}
public class EncodeMixedBinaryAndStringContents_EncodeCallback : IEncodeCallback
{
public void Call(object data)
{
Parser.DecodePayload((byte[]) data, new EncodeMixedBinaryAndStringContents_DecodeCallback());
}
public class EncodeMixedBinaryAndStringContents_DecodeCallback : IDecodePayloadCallback
{
public bool Call(Packet packet, int index, int total)
{
if (index == 0)
{
Assert.Equal(Packet.MESSAGE, packet.Type);
Assert.Equal(ThirdBuffer(), packet.Data);
}
else if (index == 1)
{
Assert.Equal(Packet.MESSAGE, packet.Type);
Assert.Equal("hello", packet.Data);
}
else
{
Assert.Equal(Packet.CLOSE, packet.Type);
}
return true;
}
}
}
[Fact]
public void EncodeMixedBinaryAndStringContents()
{
var packets = new Packet[]
{
new Packet(Packet.MESSAGE, ThirdBuffer()),
new Packet(Packet.MESSAGE, "hello"),
new Packet(Packet.CLOSE),
};
Parser.EncodePayload(packets, new EncodeMixedBinaryAndStringContents_EncodeCallback());
}
}
}

View File

@@ -0,0 +1,35 @@
using System.Reflection;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("EngineIoClientDotNet")]
[assembly: AssemblyDescription("Engine.IO Client Library for .Net")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Quobject Software")]
[assembly: AssemblyProduct("EngineIoClientDotNet")]
[assembly: AssemblyCopyright("Copyright © 2014")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("a95e75cd-35e6-4e88-9e22-631e3fd01546")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("0.9.4")]
[assembly: AssemblyFileVersion("0.9.4")]

View File

@@ -0,0 +1,43 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.NETCore.Platforms" version="1.1.0" targetFramework="net45" />
<package id="NETStandard.Library" version="1.6.1" targetFramework="net45" />
<package id="Newtonsoft.Json" version="10.0.1" targetFramework="net45" />
<package id="SuperSocket.ClientEngine.Core" version="0.8.0.8" targetFramework="net45" />
<package id="System.Collections" version="4.3.0" targetFramework="net45" />
<package id="System.Collections.Concurrent" version="4.3.0" targetFramework="net45" />
<package id="System.Diagnostics.Debug" version="4.3.0" targetFramework="net45" />
<package id="System.Diagnostics.Tools" version="4.3.0" targetFramework="net45" />
<package id="System.Diagnostics.Tracing" version="4.3.0" targetFramework="net45" />
<package id="System.Globalization" version="4.3.0" targetFramework="net45" />
<package id="System.IO" version="4.3.0" targetFramework="net45" />
<package id="System.IO.Compression" version="4.3.0" targetFramework="net45" />
<package id="System.Linq" version="4.3.0" targetFramework="net45" />
<package id="System.Linq.Expressions" version="4.3.0" targetFramework="net45" />
<package id="System.Net.Http" version="4.3.1" targetFramework="net45" />
<package id="System.Net.Primitives" version="4.3.0" targetFramework="net45" />
<package id="System.ObjectModel" version="4.3.0" targetFramework="net45" />
<package id="System.Reflection" version="4.3.0" targetFramework="net45" />
<package id="System.Reflection.Extensions" version="4.3.0" targetFramework="net45" />
<package id="System.Reflection.Primitives" version="4.3.0" targetFramework="net45" />
<package id="System.Resources.ResourceManager" version="4.3.0" targetFramework="net45" />
<package id="System.Runtime" version="4.3.0" targetFramework="net45" />
<package id="System.Runtime.Extensions" version="4.3.0" targetFramework="net45" />
<package id="System.Runtime.InteropServices" version="4.3.0" targetFramework="net45" />
<package id="System.Runtime.InteropServices.RuntimeInformation" version="4.3.0" targetFramework="net45" />
<package id="System.Runtime.Numerics" version="4.3.0" targetFramework="net45" />
<package id="System.Text.Encoding" version="4.3.0" targetFramework="net45" />
<package id="System.Text.Encoding.Extensions" version="4.3.0" targetFramework="net45" />
<package id="System.Text.RegularExpressions" version="4.3.0" targetFramework="net45" />
<package id="System.Threading" version="4.3.0" targetFramework="net45" />
<package id="System.Threading.Tasks" version="4.3.0" targetFramework="net45" />
<package id="System.Xml.ReaderWriter" version="4.3.0" targetFramework="net45" />
<package id="System.Xml.XDocument" version="4.3.0" targetFramework="net45" />
<package id="WebSocket4Net" version="0.15.0-beta6" targetFramework="net45" />
<package id="xunit" version="2.2.0" targetFramework="net45" />
<package id="xunit.abstractions" version="2.0.1" targetFramework="net45" />
<package id="xunit.assert" version="2.2.0" targetFramework="net45" />
<package id="xunit.core" version="2.2.0" targetFramework="net45" />
<package id="xunit.extensibility.core" version="2.2.0" targetFramework="net45" />
<package id="xunit.extensibility.execution" version="2.2.0" targetFramework="net45" />
</packages>

View File

@@ -0,0 +1,186 @@
using Quobject.EngineIoClientDotNet.Client;
using Quobject.EngineIoClientDotNet.Modules;
using System.Collections.Generic;
using System.Threading;
using Xunit;
namespace Quobject.EngineIoClientDotNet_Tests.ClientTests
{
public class BinaryPollingTest : Connection
{
//[Fact]
//public void PingTest()
//{
// var log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod());
// log.Info("Start");
// var binaryData = new byte[5];
// for (int i = 0; i < binaryData.Length; i++)
// {
// binaryData[i] = (byte)i;
// }
// var events = new Queue<object>();
// var options = CreateOptions();
// options.Transports = new List<string>(){"polling"};
// var socket = new Socket(options);
// socket.On(Socket.EVENT_OPEN, () =>
// {
// log.Info("EVENT_OPEN");
// socket.Send(binaryData);
// socket.Send("cash money €€€");
// });
// socket.On(Socket.EVENT_MESSAGE, (d) =>
// {
// var data = d as string;
// log.Info(string.Format("EVENT_MESSAGE data ={0} d = {1} ", data, d));
// if (data == "hi")
// {
// return;
// }
// events.Enqueue(d);
// //socket.Close();
// });
// socket.Open();
// Task.Delay(20000).Wait();
// socket.Close();
// log.Info("ReceiveBinaryData end");
// var binaryData2 = new byte[5];
// for (int i = 0; i < binaryData2.Length; i++)
// {
// binaryData2[i] = (byte)(i + 1);
// }
// object result;
// events.TryDequeue(out result);
// Assert.Equal("1", "1");
//}
private ManualResetEvent _manualResetEvent = null;
[Fact]
public void ReceiveBinaryData()
{
var log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod());
log.Info("Start");
_manualResetEvent = new ManualResetEvent(false);
var events = new Queue<object>();
var binaryData = new byte[5];
for (int i = 0; i < binaryData.Length; i++)
{
binaryData[i] = (byte)i;
}
var options = CreateOptions();
options.Transports = new List<string>() { "polling" };
var socket = new Socket(options);
socket.On(Socket.EVENT_OPEN, () =>
{
log.Info("EVENT_OPEN");
socket.Send(binaryData);
//socket.Send("cash money €€€");
});
socket.On(Socket.EVENT_MESSAGE, (d) =>
{
var data = d as string;
log.Info(string.Format("EVENT_MESSAGE data ={0} d = {1} ", data, d));
if (data == "hi")
{
return;
}
events.Enqueue(d);
_manualResetEvent.Set();
});
socket.Open();
_manualResetEvent.WaitOne();
socket.Close();
log.Info("ReceiveBinaryData end");
var binaryData2 = new byte[5];
for (int i = 0; i < binaryData2.Length; i++)
{
binaryData2[i] = (byte)(i + 1);
}
object result;
result = events.Dequeue();
Assert.Equal(binaryData, result);
}
[Fact]
public void ReceiveBinaryDataAndMultibyteUTF8String()
{
var log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod());
log.Info("Start");
_manualResetEvent = new ManualResetEvent(false);
var events = new Queue<object>();
var binaryData = new byte[5];
for (int i = 0; i < binaryData.Length; i++)
{
binaryData[i] = (byte)i;
}
const string stringData = "cash money €€€";
var options = CreateOptions();
options.Transports = new List<string>() { "polling" };
var socket = new Socket(options);
socket.On(Socket.EVENT_OPEN, () =>
{
log.Info("EVENT_OPEN");
socket.On(Socket.EVENT_MESSAGE, (d) =>
{
var data = d as string;
log.Info(string.Format("EVENT_MESSAGE data ={0} d = {1} ", data, d));
if (data == "hi")
{
return;
}
events.Enqueue(d);
if (events.Count > 1)
{
_manualResetEvent.Set();
}
});
socket.Send(binaryData);
socket.Send(stringData);
});
socket.Open();
_manualResetEvent.WaitOne();
socket.Close();
var binaryData2 = new byte[5];
for (int i = 0; i < binaryData2.Length; i++)
{
binaryData2[i] = (byte)(i + 1);
}
object result;
result = events.Dequeue();
Assert.Equal(binaryData, result);
result = events.Dequeue();
Assert.Equal(stringData, (string)result);
socket.Close();
}
}
}

View File

@@ -0,0 +1,138 @@
using Quobject.EngineIoClientDotNet.Client;
using Quobject.EngineIoClientDotNet.Modules;
using System.Collections.Generic;
using System.Threading;
using Xunit;
namespace Quobject.EngineIoClientDotNet_Tests.ClientTests
{
public class BinaryWebSocketTest : Connection
{
private ManualResetEvent _manualResetEvent = null;
[Fact]
public void ReceiveBinaryData()
{
var log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod());
log.Info("Start");
_manualResetEvent = new ManualResetEvent(false);
var events = new Queue<object>();
var binaryData = new byte[5];
for (int i = 0; i < binaryData.Length; i++)
{
binaryData[i] = (byte)(i + 0);
}
var options = CreateOptions();
var socket = new Socket(options);
socket.On(Socket.EVENT_OPEN, () =>
{
log.Info(Socket.EVENT_OPEN);
});
socket.On(Socket.EVENT_UPGRADE, () =>
{
log.Info(Socket.EVENT_UPGRADE);
socket.Send(binaryData);
});
socket.On(Socket.EVENT_MESSAGE, (d) =>
{
var data = d as string;
log.Info(string.Format("EVENT_MESSAGE data ={0} d = {1} ", data, d));
if (data == "hi")
{
return;
}
events.Enqueue(d);
_manualResetEvent.Set();
});
socket.Open();
_manualResetEvent.WaitOne();
socket.Close();
log.Info("ReceiveBinaryData end");
var binaryData2 = new byte[5];
for (int i = 0; i < binaryData2.Length; i++)
{
binaryData2[i] = (byte)(i + 1);
}
object result;
result = events.Dequeue();
Assert.Equal(binaryData, result);
}
[Fact]
public void ReceiveBinaryDataAndMultibyteUTF8String()
{
var log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod());
log.Info("Start");
_manualResetEvent = new ManualResetEvent(false);
var events = new Queue<object>();
var binaryData = new byte[5];
for (int i = 0; i < binaryData.Length; i++)
{
binaryData[i] = (byte)i;
}
const string stringData = "Ä ä Ü ü ß";
var options = CreateOptions();
var socket = new Socket(options);
socket.On(Socket.EVENT_OPEN, () =>
{
log.Info("EVENT_OPEN");
});
socket.On(Socket.EVENT_UPGRADE, () =>
{
log.Info(Socket.EVENT_UPGRADE);
socket.Send(binaryData);
socket.Send(stringData);
});
socket.On(Socket.EVENT_MESSAGE, (d) =>
{
var data = d as string;
log.Info(string.Format("EVENT_MESSAGE data ={0} d = {1} ", data, d));
if (data == "hi")
{
return;
}
events.Enqueue(d);
if (events.Count > 1)
{
_manualResetEvent.Set();
}
});
socket.Open();
_manualResetEvent.WaitOne();
socket.Close();
var binaryData2 = new byte[5];
for (int i = 0; i < binaryData2.Length; i++)
{
binaryData2[i] = (byte)(i + 1);
}
object result;
result = events.Dequeue();
Assert.Equal(binaryData, result);
result = events.Dequeue();
Assert.Equal(stringData, (string)result);
log.Info("ReceiveBinaryDataAndMultibyteUTF8String end");
}
}
}

View File

@@ -0,0 +1,44 @@
using Quobject.EngineIoClientDotNet.Client;
using Quobject.EngineIoClientDotNet.Modules;
namespace Quobject.EngineIoClientDotNet_Tests.ClientTests
{
public class Connection
{
static Connection()
{
LogManager.SetupLogManager();
}
protected Socket.Options CreateOptions()
{
var log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod());
//var config = ConfigBase.Load();
var options = new Socket.Options
{
Port = ConnectionConstants.PORT,
Hostname = ConnectionConstants.HOSTNAME
};
log.Info("Please add to your hosts file: 127.0.0.1 " + options.Hostname);
return options;
}
protected Socket.Options CreateOptionsSecure()
{
var log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod());
//var config = ConfigBase.Load();
var options = new Socket.Options
{
Port = ConnectionConstants.SSL_PORT,
Hostname = ConnectionConstants.HOSTNAME,
Secure = true,
IgnoreServerCertificateValidation = true
};
log.Info("Please add to your hosts file: 127.0.0.1 " + options.Hostname);
return options;
}
}
}

View File

@@ -0,0 +1,10 @@
namespace Quobject.EngineIoClientDotNet_Tests.ClientTests
{
public static class ConnectionConstants
{
public static int PORT = 80;
public static string HOSTNAME = "testme.quobject.com";
public static int SSL_PORT = 443;
public static readonly int TIMEOUT = 300000;
}
}

View File

@@ -0,0 +1,227 @@
using Quobject.EngineIoClientDotNet.Client;
using Quobject.EngineIoClientDotNet.ComponentEmitter;
using Quobject.EngineIoClientDotNet.Modules;
using System;
using System.Collections.Generic;
using System.Threading;
using Xunit;
namespace Quobject.EngineIoClientDotNet_Tests.ClientTests
{
public class ConnectionTest : Connection
{
private ManualResetEvent _manualResetEvent = null;
private Socket socket;
public string Message;
[Fact]
public void ConnectToLocalhost()
{
var log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod());
log.Info("Start");
_manualResetEvent = new ManualResetEvent(false);
var options = CreateOptions();
socket = new Socket(options);
socket.On(Socket.EVENT_OPEN, new TestListener());
socket.On(Socket.EVENT_MESSAGE, new MessageListener(socket, this));
socket.Open();
_manualResetEvent.WaitOne();
socket.Close();
Assert.Equal("hi", this.Message);
}
public class TestListener : IListener
{
public void Call(params object[] args)
{
var log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod());
log.Info("open");
}
public int CompareTo(IListener other)
{
return this.GetId().CompareTo(other.GetId());
}
public int GetId()
{
return 0;
}
}
public class MessageListener : IListener
{
private Socket socket;
private ConnectionTest connectionTest;
public MessageListener(Socket socket)
{
this.socket = socket;
}
public MessageListener(Socket socket, ConnectionTest connectionTest)
{
this.socket = socket;
this.connectionTest = connectionTest;
}
public void Call(params object[] args)
{
var log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod());
log.Info("message = " + args[0]);
connectionTest.Message = (string)args[0];
connectionTest._manualResetEvent.Set();
}
public int CompareTo(IListener other)
{
return this.GetId().CompareTo(other.GetId());
}
public int GetId()
{
return 0;
}
}
[Fact]
public void ConnectToLocalhost2()
{
var log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod());
log.Info("Start");
_manualResetEvent = new ManualResetEvent(false);
this.Message = "";
var options = CreateOptions();
options.Transports = new List<string>() { "polling" };
socket = new Socket(options);
//socket = new Socket(CreateOptions());
socket.On(Socket.EVENT_OPEN, () =>
{
log.Info("open");
//socket.Send("test send");
});
socket.On(Socket.EVENT_MESSAGE, (d) =>
{
var data = (string)d;
log.Info("message2 = " + data);
this.Message = data;
_manualResetEvent.Set();
});
socket.Open();
_manualResetEvent.WaitOne();
socket.Close();
Assert.Equal("hi", this.Message);
}
[Fact]
public void TestmultibyteUtf8StringsWithPolling()
{
var log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod());
log.Info("Start");
_manualResetEvent = new ManualResetEvent(false);
const string SendMessage = "cash money €€€";
socket = new Socket(CreateOptions());
socket.On(Socket.EVENT_OPEN, () =>
{
log.Info("open");
socket.Send(SendMessage);
});
socket.On(Socket.EVENT_MESSAGE, (d) =>
{
var data = (string)d;
log.Info("TestMessage data = " + data);
if (data == "hi")
{
return;
}
this.Message = data;
_manualResetEvent.Set();
});
socket.Open();
_manualResetEvent.WaitOne();
socket.Close();
log.Info("TestmultibyteUtf8StringsWithPolling this.Message = " + this.Message);
Assert.Equal(SendMessage, this.Message);
}
[Fact]
public void Testemoji()
{
var log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod());
log.Info("Start");
_manualResetEvent = new ManualResetEvent(false);
const string SendMessage = "\uD800-\uDB7F\uDB80-\uDBFF\uDC00-\uDFFF\uE000-\uF8FF";
var options = CreateOptions();
socket = new Socket(options);
socket.On(Socket.EVENT_OPEN, () =>
{
log.Info("open");
socket.Send(SendMessage);
});
socket.On(Socket.EVENT_MESSAGE, (d) =>
{
var data = (string)d;
log.Info(Socket.EVENT_MESSAGE);
if (data == "hi")
{
return;
}
this.Message = data;
_manualResetEvent.Set();
});
socket.Open();
_manualResetEvent.WaitOne();
socket.Close();
Assert.True(SendMessage == this.Message);
}
[Fact]
public void NotSendPacketsIfSocketCloses()
{
var log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod());
log.Info("Start");
var noPacket = true;
socket = new Socket(CreateOptions());
socket.On(Socket.EVENT_OPEN, () =>
{
noPacket = true;
});
socket.Open();
socket.On(Socket.EVENT_PACKET_CREATE, () =>
{
noPacket = false;
log.Info("NotSendPacketsIfSocketCloses EVENT_PACKET_CREATE noPacket = " + noPacket);
});
socket.Close();
System.Threading.Thread.Sleep(TimeSpan.FromSeconds(1));
//await Task.Delay(1000);
log.Info("NotSendPacketsIfSocketCloses end noPacket = " + noPacket);
Assert.True(noPacket);
}
}
}

View File

@@ -0,0 +1,26 @@
using Quobject.EngineIoClientDotNet.Client;
using Xunit;
namespace Quobject.EngineIoClientDotNet_Tests.ClientTests
{
public class HandshakeDataTests
{
[Fact]
public void Test()
{
var json = @"{
sid: 'nne323',
upgrades: ['u1','u2'],
pingInterval: 12,
pingTimeout: 23
}";
var handshakeData = new HandshakeData(json);
Assert.Equal("u1", handshakeData.Upgrades[0]);
Assert.Equal("u2", handshakeData.Upgrades[1]);
Assert.Equal(12, handshakeData.PingInterval);
Assert.Equal(23, handshakeData.PingTimeout);
}
}
}

View File

@@ -0,0 +1,283 @@
using Quobject.EngineIoClientDotNet.Client;
using Quobject.EngineIoClientDotNet.Client.Transports;
using Quobject.EngineIoClientDotNet.ComponentEmitter;
using Quobject.EngineIoClientDotNet.Modules;
using System.Collections.Generic;
using System.Threading;
using Xunit;
namespace Quobject.EngineIoClientDotNet_Tests.ClientTests
{
public class SSLServerConnectionTest : Connection
{
private ManualResetEvent _manualResetEvent = null;
[Fact]
public void OpenAndClose()
{
var log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod());
log.Info("Start");
_manualResetEvent = new ManualResetEvent(false);
var events = new Queue<string>();
var socket = new Socket(CreateOptionsSecure());
socket.On(Socket.EVENT_OPEN, () =>
{
log.Info("EVENT_OPEN");
events.Enqueue(Socket.EVENT_OPEN);
socket.Close();
});
socket.On(Socket.EVENT_CLOSE, () =>
{
log.Info("EVENT_CLOSE");
events.Enqueue(Socket.EVENT_CLOSE);
_manualResetEvent.Set();
});
socket.Open();
_manualResetEvent.WaitOne();
socket.Close();
string result;
result = events.Dequeue();
Assert.Equal(Socket.EVENT_OPEN, result);
result = events.Dequeue();
Assert.Equal(Socket.EVENT_CLOSE, result);
}
[Fact]
public void Messages()
{
var log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod());
log.Info("Start");
_manualResetEvent = new ManualResetEvent(false);
var events = new Queue<string>();
var socket = new Socket(CreateOptionsSecure());
socket.On(Socket.EVENT_OPEN, () =>
{
log.Info("EVENT_OPEN");
socket.Send("hello");
});
socket.On(Socket.EVENT_MESSAGE, (d) =>
{
var data = (string)d;
log.Info("EVENT_MESSAGE data = " + data);
events.Enqueue(data);
if (events.Count > 1)
{
_manualResetEvent.Set();
}
});
socket.Open();
_manualResetEvent.WaitOne();
socket.Close();
string result;
result = events.Dequeue();
Assert.Equal("hi", result);
result = events.Dequeue();
Assert.Equal("hello", result);
}
[Fact]
public void Handshake()
{
var log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod());
log.Info("Start");
_manualResetEvent = new ManualResetEvent(false);
HandshakeData handshake_data = null;
var socket = new Socket(CreateOptionsSecure());
socket.On(Socket.EVENT_HANDSHAKE, (data) =>
{
log.Info(Socket.EVENT_HANDSHAKE + string.Format(" data = {0}", data));
handshake_data = data as HandshakeData;
_manualResetEvent.Set();
});
socket.Open();
_manualResetEvent.WaitOne();
socket.Close();
Assert.NotNull(handshake_data);
Assert.NotNull(handshake_data.Upgrades);
Assert.True(handshake_data.Upgrades.Count > 0);
Assert.True(handshake_data.PingInterval > 0);
Assert.True(handshake_data.PingTimeout > 0);
}
public class TestHandshakeListener : IListener
{
public HandshakeData HandshakeData;
private SSLServerConnectionTest serverConnectionTest;
public TestHandshakeListener(SSLServerConnectionTest serverConnectionTest)
{
this.serverConnectionTest = serverConnectionTest;
}
public void Call(params object[] args)
{
var log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod());
log.Info(string.Format("open args[0]={0} args.Length={1}", args[0], args.Length));
HandshakeData = args[0] as HandshakeData;
serverConnectionTest._manualResetEvent.Set();
}
public int CompareTo(IListener other)
{
return this.GetId().CompareTo(other.GetId());
}
public int GetId()
{
return 0;
}
}
[Fact]
public void Handshake2()
{
var log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod());
log.Info("Start");
_manualResetEvent = new ManualResetEvent(false);
var socket = new Socket(CreateOptionsSecure());
var testListener = new TestHandshakeListener(this);
socket.On(Socket.EVENT_HANDSHAKE, testListener);
socket.Open();
_manualResetEvent.WaitOne();
socket.Close();
Assert.NotNull(testListener.HandshakeData);
Assert.NotNull(testListener.HandshakeData.Upgrades);
Assert.True(testListener.HandshakeData.Upgrades.Count > 0);
Assert.True(testListener.HandshakeData.PingInterval > 0);
Assert.True(testListener.HandshakeData.PingTimeout > 0);
}
[Fact]
public void Upgrade()
{
var log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod());
log.Info("Start");
_manualResetEvent = new ManualResetEvent(false);
var events = new Queue<object>();
var socket = new Socket(CreateOptionsSecure());
socket.On(Socket.EVENT_UPGRADING, (data) =>
{
log.Info(Socket.EVENT_UPGRADING + string.Format(" data = {0}", data));
events.Enqueue(data);
});
socket.On(Socket.EVENT_UPGRADE, (data) =>
{
log.Info(Socket.EVENT_UPGRADE + string.Format(" data = {0}", data));
events.Enqueue(data);
_manualResetEvent.Set();
});
socket.Open();
_manualResetEvent.WaitOne();
object test = null;
test = events.Dequeue();
Assert.NotNull(test);
Assert.IsAssignableFrom<Transport>(test);
test = events.Dequeue();
Assert.NotNull(test);
Assert.IsAssignableFrom<Transport>(test);
}
[Fact]
public void RememberWebsocket()
{
var log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod());
log.Info("Start");
_manualResetEvent = new ManualResetEvent(false);
var socket1 = new Socket(CreateOptionsSecure());
string socket1TransportName = null;
string socket2TransportName = null;
socket1.On(Socket.EVENT_OPEN, () =>
{
log.Info("EVENT_OPEN");
socket1TransportName = socket1.Transport.Name;
});
socket1.On(Socket.EVENT_UPGRADE, (data) =>
{
log.Info(Socket.EVENT_UPGRADE + string.Format(" data = {0}", data));
var transport = (Transport)data;
socket1.Close();
if (WebSocket.NAME == transport.Name)
{
var options = CreateOptionsSecure();
options.RememberUpgrade = true;
var socket2 = new Socket(options);
socket2.Open();
socket2TransportName = socket2.Transport.Name;
socket2.Close();
_manualResetEvent.Set();
}
});
socket1.Open();
_manualResetEvent.WaitOne();
Assert.Equal(Polling.NAME, socket1TransportName);
Assert.Equal(WebSocket.NAME, socket2TransportName);
}
[Fact]
public void NotRememberWebsocket()
{
var log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod());
log.Info("Start");
_manualResetEvent = new ManualResetEvent(false);
var socket1 = new Socket(CreateOptionsSecure());
string socket1TransportName = null;
string socket2TransportName = null;
socket1.On(Socket.EVENT_OPEN, () =>
{
log.Info("EVENT_OPEN");
socket1TransportName = socket1.Transport.Name;
});
socket1.On(Socket.EVENT_UPGRADE, (data) =>
{
log.Info(Socket.EVENT_UPGRADE + string.Format(" data = {0}", data));
var transport = (Transport)data;
if (WebSocket.NAME == transport.Name)
{
socket1.Close();
var options = CreateOptionsSecure();
options.RememberUpgrade = false;
var socket2 = new Socket(options);
socket2.On(Socket.EVENT_OPEN, () =>
{
log.Info("EVENT_OPEN socket 2");
socket2TransportName = socket2.Transport.Name;
socket2.Close();
_manualResetEvent.Set();
});
socket2.Open();
}
});
socket1.Open();
_manualResetEvent.WaitOne();
Assert.Equal(Polling.NAME, socket1TransportName);
Assert.Equal(Polling.NAME, socket2TransportName);
}
}
}

View File

@@ -0,0 +1,373 @@
using Quobject.EngineIoClientDotNet.Client;
using Quobject.EngineIoClientDotNet.Client.Transports;
using Quobject.EngineIoClientDotNet.ComponentEmitter;
using Quobject.EngineIoClientDotNet.Modules;
using System.Collections.Generic;
using System.Threading;
using Xunit;
namespace Quobject.EngineIoClientDotNet_Tests.ClientTests
{
public class ServerConnectionTest : Connection
{
private ManualResetEvent _manualResetEvent = null;
[Fact]
public void OpenAndClose()
{
var log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod());
log.Info("Start");
_manualResetEvent = new ManualResetEvent(false);
var events = new Queue<string>();
var socket = new Socket(CreateOptions());
socket.On(Socket.EVENT_OPEN, () =>
{
log.Info("EVENT_OPEN");
events.Enqueue(Socket.EVENT_OPEN);
socket.Close();
});
socket.On(Socket.EVENT_CLOSE, () =>
{
log.Info("EVENT_CLOSE");
events.Enqueue(Socket.EVENT_CLOSE);
_manualResetEvent.Set();
});
socket.Open();
_manualResetEvent.WaitOne();
socket.Close();
string result;
result = events.Dequeue();
Assert.Equal(Socket.EVENT_OPEN, result);
result = events.Dequeue();
Assert.Equal(Socket.EVENT_CLOSE, result);
}
[Fact]
public void Messages()
{
var log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod());
log.Info("Start");
_manualResetEvent = new ManualResetEvent(false);
var events = new Queue<string>();
var socket = new Socket(CreateOptions());
socket.On(Socket.EVENT_OPEN, () =>
{
log.Info("EVENT_OPEN");
socket.Send("hello");
});
socket.On(Socket.EVENT_MESSAGE, (d) =>
{
var data = (string)d;
log.Info("EVENT_MESSAGE data = " + data);
events.Enqueue(data);
if (events.Count > 1)
{
_manualResetEvent.Set();
}
});
socket.Open();
_manualResetEvent.WaitOne();
socket.Close();
string result;
result = events.Dequeue();
Assert.Equal("hi", result);
result = events.Dequeue();
Assert.Equal("hello", result);
}
[Fact]
public void Handshake()
{
var log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod());
log.Info("Start");
_manualResetEvent = new ManualResetEvent(false);
HandshakeData handshake_data = null;
var socket = new Socket(CreateOptions());
socket.On(Socket.EVENT_HANDSHAKE, (data) =>
{
log.Info(Socket.EVENT_HANDSHAKE + string.Format(" data = {0}", data));
handshake_data = data as HandshakeData;
_manualResetEvent.Set();
});
socket.Open();
_manualResetEvent.WaitOne();
socket.Close();
Assert.NotNull(handshake_data);
Assert.NotNull(handshake_data.Upgrades);
Assert.True(handshake_data.Upgrades.Count > 0);
Assert.True(handshake_data.PingInterval > 0);
Assert.True(handshake_data.PingTimeout > 0);
}
public class TestHandshakeListener : IListener
{
public HandshakeData HandshakeData;
private ServerConnectionTest serverConnectionTest;
public TestHandshakeListener(ServerConnectionTest serverConnectionTest)
{
this.serverConnectionTest = serverConnectionTest;
}
public void Call(params object[] args)
{
var log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod());
log.Info(string.Format("open args[0]={0} args.Length={1}", args[0], args.Length));
HandshakeData = args[0] as HandshakeData;
serverConnectionTest._manualResetEvent.Set();
}
public int CompareTo(IListener other)
{
return this.GetId().CompareTo(other.GetId());
}
public int GetId()
{
return 0;
}
}
[Fact]
public void Handshake2()
{
var log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod());
log.Info("Start");
_manualResetEvent = new ManualResetEvent(false);
var socket = new Socket(CreateOptions());
var testListener = new TestHandshakeListener(this);
socket.On(Socket.EVENT_HANDSHAKE, testListener);
socket.Open();
_manualResetEvent.WaitOne();
socket.Close();
Assert.NotNull(testListener.HandshakeData);
Assert.NotNull(testListener.HandshakeData.Upgrades);
Assert.True(testListener.HandshakeData.Upgrades.Count > 0);
Assert.True(testListener.HandshakeData.PingInterval > 0);
Assert.True(testListener.HandshakeData.PingTimeout > 0);
}
[Fact]
public void Upgrade()
{
var log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod());
log.Info("Start");
_manualResetEvent = new ManualResetEvent(false);
var events = new Queue<object>();
var socket = new Socket(CreateOptions());
socket.On(Socket.EVENT_UPGRADING, (data) =>
{
log.Info(Socket.EVENT_UPGRADING + string.Format(" data = {0}", data));
events.Enqueue(data);
});
socket.On(Socket.EVENT_UPGRADE, (data) =>
{
log.Info(Socket.EVENT_UPGRADE + string.Format(" data = {0}", data));
events.Enqueue(data);
_manualResetEvent.Set();
});
socket.Open();
_manualResetEvent.WaitOne();
object test = null;
test = events.Dequeue();
Assert.NotNull(test);
Assert.IsAssignableFrom<Transport>(test);
test = events.Dequeue();
Assert.NotNull(test);
Assert.IsAssignableFrom<Transport>(test);
}
[Fact]
public void RememberWebsocket()
{
var log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod());
log.Info("Start");
_manualResetEvent = new ManualResetEvent(false);
var socket1 = new Socket(CreateOptions());
string socket1TransportName = null;
string socket2TransportName = null;
socket1.On(Socket.EVENT_OPEN, () =>
{
log.Info("EVENT_OPEN");
socket1TransportName = socket1.Transport.Name;
});
socket1.On(Socket.EVENT_UPGRADE, (data) =>
{
log.Info(Socket.EVENT_UPGRADE + string.Format(" data = {0}", data));
var transport = (Transport)data;
socket1.Close();
if (WebSocket.NAME == transport.Name)
{
var options = CreateOptions();
options.RememberUpgrade = true;
var socket2 = new Socket(options);
socket2.Open();
socket2TransportName = socket2.Transport.Name;
socket2.Close();
_manualResetEvent.Set();
}
});
socket1.Open();
_manualResetEvent.WaitOne();
Assert.Equal(Polling.NAME, socket1TransportName);
Assert.Equal(WebSocket.NAME, socket2TransportName);
}
[Fact]
public void NotRememberWebsocket()
{
var log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod());
log.Info("Start");
_manualResetEvent = new ManualResetEvent(false);
var socket1 = new Socket(CreateOptions());
string socket1TransportName = null;
string socket2TransportName = null;
socket1.On(Socket.EVENT_OPEN, () =>
{
log.Info("EVENT_OPEN");
socket1TransportName = socket1.Transport.Name;
});
socket1.On(Socket.EVENT_UPGRADE, (data) =>
{
log.Info(Socket.EVENT_UPGRADE + string.Format(" data = {0}", data));
var transport = (Transport)data;
if (WebSocket.NAME == transport.Name)
{
socket1.Close();
var options = CreateOptions();
options.RememberUpgrade = false;
var socket2 = new Socket(options);
socket2.On(Socket.EVENT_OPEN, () =>
{
log.Info("EVENT_OPEN socket 2");
socket2TransportName = socket2.Transport.Name;
socket2.Close();
_manualResetEvent.Set();
});
socket2.Open();
}
});
socket1.Open();
_manualResetEvent.WaitOne();
Assert.Equal(Polling.NAME, socket1TransportName);
Assert.Equal(Polling.NAME, socket2TransportName);
}
[Fact]
public void Cookie()
{
var log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod());
log.Info("Start");
_manualResetEvent = new ManualResetEvent(false);
var events = new Queue<string>();
var options = CreateOptions();
options.Cookies.Add("foo", "bar");
var socket = new Socket(options);
socket.On(Socket.EVENT_OPEN, () =>
{
log.Info("EVENT_OPEN");
socket.Send("cookie");
});
socket.On(Socket.EVENT_MESSAGE, (d) =>
{
var data = (string)d;
log.Info("EVENT_MESSAGE data = " + data);
events.Enqueue(data);
if (events.Count > 1)
{
_manualResetEvent.Set();
}
});
socket.Open();
_manualResetEvent.WaitOne();
socket.Close();
string result;
result = events.Dequeue();
Assert.Equal("hi", result);
result = events.Dequeue();
Assert.Equal("got cookie", result);
}
[Fact]
public void UpgradeCookie()
{
var log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod());
log.Info("Start");
_manualResetEvent = new ManualResetEvent(false);
var events = new Queue<object>();
var options = CreateOptions();
options.Cookies.Add("foo", "bar");
var socket = new Socket(options);
socket.On(Socket.EVENT_UPGRADING, (data) =>
{
log.Info(Socket.EVENT_UPGRADING + string.Format(" data = {0}", data));
events.Enqueue(data);
});
socket.On(Socket.EVENT_UPGRADE, (data) =>
{
log.Info(Socket.EVENT_UPGRADE + string.Format(" data = {0}", data));
events.Enqueue(data);
socket.Send("cookie");
});
socket.On(Socket.EVENT_MESSAGE, (d) =>
{
if (events.Count > 1)
{
var data = (string)d;
log.Info("EVENT_MESSAGE data = " + data);
events.Enqueue(data);
_manualResetEvent.Set();
}
});
socket.Open();
_manualResetEvent.WaitOne();
object test = null;
test = events.Dequeue();
Assert.NotNull(test);
Assert.IsAssignableFrom<Transport>(test);
test = events.Dequeue();
Assert.NotNull(test);
Assert.IsAssignableFrom<Transport>(test);
test = events.Dequeue();
Assert.Equal("got cookie", test);
}
}
}

View File

@@ -0,0 +1,77 @@
using Quobject.EngineIoClientDotNet.Client;
using Quobject.EngineIoClientDotNet.Modules;
using System;
using System.Collections.Generic;
using Xunit;
namespace Quobject.EngineIoClientDotNet_Tests.ClientTests
{
public class SocketTest : Connection
{
private Socket socket;
public string Message;
[Fact]
public void FilterUpgrades()
{
var log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod());
log.Info("Start");
var options = CreateOptions();
options.Transports = new List<string>() { "polling" };
socket = new Socket(options);
var List = socket.FilterUpgrades(new List<string>() { "polling", "websocket" });
Assert.Equal("polling", List[0]);
Assert.Equal(1, List.Count);
}
[Fact]
public void SocketClosing()
{
var log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod());
log.Info("Start");
var closed = false;
var error = false;
var options = CreateOptions();
socket = new Socket("ws://0.0.0.0:8080", options);
socket.On(Socket.EVENT_OPEN, () =>
{
log.Info("EVENT_OPEN");
//socket.Send("test send");
});
socket.On(Socket.EVENT_CLOSE, () =>
{
log.Info("EVENT_CLOSE = ");
closed = true;
});
socket.Once(Socket.EVENT_ERROR, () =>
{
log.Info("EVENT_ERROR = ");
error = true;
});
socket.Open();
System.Threading.Thread.Sleep(TimeSpan.FromSeconds(5));
//Task.Delay(1000);
Assert.True(closed);
Assert.True(error);
}
[Fact]
public void SocketOptionCookies()
{
var options = new Socket.Options();
options.Cookies.Add("foo", "bar");
Assert.Equal("foo=bar", options.GetCookiesAsString());
options.Cookies.Add("name2", "value2");
Assert.Equal("foo=bar; name2=value2", options.GetCookiesAsString());
}
}
}

View File

@@ -0,0 +1,182 @@
using Quobject.EngineIoClientDotNet.Client;
using Quobject.EngineIoClientDotNet.Client.Transports;
using Quobject.EngineIoClientDotNet.Modules;
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using Xunit;
namespace Quobject.EngineIoClientDotNet_Tests.ClientTests
{
// NOTE: tests for the rememberUpgrade option are on ServerConnectionTest.
public class TransportTest : Connection
{
[Fact]
public void Constructors()
{
var log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod());
log.Info("Start");
var socket = new Socket(CreateOptions());
socket.Open();
System.Threading.Thread.Sleep(TimeSpan.FromSeconds(3));
Assert.NotNull(socket.Transport);
socket.Close();
}
[Fact]
public void Uri()
{
var log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod());
log.Info("Start");
var options = new Transport.Options();
options.Path = "/engine.io";
options.Hostname = this.CreateOptions().Hostname;
options.Secure = false;
options.Query = new Dictionary<string, string> { { "sid", "test" } };
options.TimestampRequests = false;
var polling = new Polling(options);
var expected = string.Format("http://{0}/engine.io?sid=test&b64=1", options.Hostname);
Assert.Contains(expected, polling.Uri());
}
[Fact]
public void UriWithDefaultPort()
{
var log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod());
log.Info("Start");
var options = new Transport.Options();
options.Path = "/engine.io";
options.Hostname = this.CreateOptions().Hostname;
options.Secure = false;
options.Query = new Dictionary<string, string> { { "sid", "test" } };
options.TimestampRequests = false;
options.Port = 80;
var polling = new Polling(options);
//Assert.Contains("http://localhost/engine.io?sid=test&b64=1", polling.Uri());
var expected = string.Format("http://{0}/engine.io?sid=test&b64=1", options.Hostname);
Assert.Contains(expected, polling.Uri());
}
[Fact]
public void UriWithPort()
{
var log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod());
log.Info("Start");
var options = new Transport.Options();
options.Path = "/engine.io";
options.Hostname = this.CreateOptions().Hostname;
options.Secure = false;
options.Query = new Dictionary<string, string> { { "sid", "test" } };
options.TimestampRequests = false;
options.Port = 3000;
var polling = new Polling(options);
//Assert.Contains("http://localhost:3000/engine.io?sid=test&b64=1", polling.Uri());
var expected = string.Format("http://{0}:{1}/engine.io?sid=test&b64=1", options.Hostname, options.Port);
Assert.Contains(expected, polling.Uri());
}
[Fact]
public void HttpsUriWithDefaultPort()
{
var log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod());
log.Info("Start");
var options = new Transport.Options();
options.Path = "/engine.io";
options.Hostname = this.CreateOptions().Hostname;
options.Secure = true;
options.Query = new Dictionary<string, string> { { "sid", "test" } };
options.TimestampRequests = false;
options.Port = 443;
var polling = new Polling(options);
//Assert.Contains("https://localhost/engine.io?sid=test&b64=1", polling.Uri());
var expected = string.Format("https://{0}/engine.io?sid=test&b64=1", options.Hostname);
Assert.Contains(expected, polling.Uri());
}
[Fact]
public void TimestampedUri()
{
var log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod());
log.Info("Start");
var options = new Transport.Options();
options.Path = "/engine.io";
options.Hostname = "test";
options.Secure = false;
options.Query = new Dictionary<string, string> { { "sid", "test" } };
options.TimestampRequests = true;
options.TimestampParam = "t";
var polling = new Polling(options);
string pat = @"http://test/engine.io\?sid=test&(t=[0-9]+-[0-9]+)";
var r = new Regex(pat, RegexOptions.IgnoreCase);
var test = polling.Uri();
log.Info(test);
Match m = r.Match(test);
Assert.True(m.Success);
}
[Fact]
public void WsUri()
{
var log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod());
log.Info("Start");
var options = new Transport.Options();
options.Path = "/engine.io";
options.Hostname = "test";
options.Secure = false;
options.Query = new Dictionary<string, string> { { "transport", "websocket" } };
options.TimestampRequests = false;
var ws = new WebSocket(options);
Assert.Contains("ws://test/engine.io?transport=websocket", ws.Uri());
}
[Fact]
public void WssUri()
{
var log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod());
log.Info("Start");
var options = new Transport.Options();
options.Path = "/engine.io";
options.Hostname = "test";
options.Secure = true;
options.Query = new Dictionary<string, string> { { "transport", "websocket" } };
options.TimestampRequests = false;
var ws = new WebSocket(options);
Assert.Contains("wss://test/engine.io?transport=websocket", ws.Uri());
}
[Fact]
public void WsTimestampedUri()
{
var log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod());
log.Info("Start");
var options = new Transport.Options();
options.Path = "/engine.io";
options.Hostname = "test";
options.Secure = false;
options.Query = new Dictionary<string, string> { { "sid", "test" } };
options.TimestampRequests = true;
options.TimestampParam = "woot";
var ws = new WebSocket(options);
string pat = @"ws://test/engine.io\?sid=test&(woot=[0-9]+-[0-9]+)";
var r = new Regex(pat, RegexOptions.IgnoreCase);
var test = ws.Uri();
log.Info(test);
Match m = r.Match(test);
Assert.True(m.Success);
}
}
}

View File

@@ -0,0 +1,52 @@
using Quobject.EngineIoClientDotNet.Client;
using Quobject.EngineIoClientDotNet.Modules;
using System;
using Xunit;
namespace Quobject.EngineIoClientDotNet_Tests.ClientTests
{
public class UsageTest : Connection
{
[Fact]
public void Usage1()
{
var log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod());
log.Info("Start");
var options = CreateOptions();
var socket = new Socket(options);
//You can use `Socket` to connect:
//var socket = new Socket("ws://localhost");
socket.On(Socket.EVENT_OPEN, () =>
{
socket.Send("hi");
socket.Close();
});
socket.Open();
//System.Threading.Thread.Sleep(TimeSpan.FromSeconds(2));
}
[Fact]
public void Usage2()
{
var log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod());
log.Info("Start");
var options = CreateOptions();
var socket = new Socket(options);
//Receiving data
//var socket = new Socket("ws://localhost:3000");
socket.On(Socket.EVENT_OPEN, () =>
{
socket.On(Socket.EVENT_MESSAGE, (data) => Console.WriteLine((string)data));
});
socket.Open();
System.Threading.Thread.Sleep(TimeSpan.FromSeconds(2));
socket.Close();
}
}
}

View File

@@ -0,0 +1,399 @@
using Quobject.EngineIoClientDotNet.ComponentEmitter;
using Quobject.EngineIoClientDotNet.Modules;
using System;
using System.Collections.Generic;
using System.Linq;
using Xunit;
namespace Quobject.EngineIoClientDotNet_Tests.ComponentEmitterTests
{
public class EmitterTests
{
public class TestListener1 : IListener
{
private readonly List<object> _calls;
public TestListener1(List<object> calls)
{
this._calls = calls;
}
public void Call(params object[] args)
{
_calls.Add("one");
_calls.Add(args[0]);
}
public int CompareTo(IListener other)
{
return this.GetId().CompareTo(other.GetId());
}
public int GetId()
{
return 0;
}
}
public class TestListener2 : IListener
{
private readonly List<object> _calls;
public TestListener2(List<object> calls)
{
this._calls = calls;
}
public void Call(params object[] args)
{
_calls.Add("two");
_calls.Add(args[0]);
}
public int CompareTo(IListener other)
{
return this.GetId().CompareTo(other.GetId());
}
public int GetId()
{
return 0;
}
}
[Fact]
public void On()
{
LogManager.SetupLogManager();
var log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod());
log.Info("Start");
var emitter = new Emitter();
var calls = new List<object>();
var listener1 = new TestListener1(calls);
emitter.On("foo", listener1);
var listener2 = new TestListener2(calls);
emitter.On("foo", listener2);
emitter.Emit("foo", 1);
emitter.Emit("bar", 1);
emitter.Emit("foo", 2);
var expected = new Object[] {"one", 1, "two", 1, "one", 2, "two", 2};
Assert.Equal(expected, calls.ToArray());
}
[Fact]
public void Once()
{
LogManager.SetupLogManager();
var log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod());
log.Info("Start");
var emitter = new Emitter();
var calls = new List<object>();
var listener1 = new TestListener1(calls);
emitter.Once("foo", listener1);
emitter.Emit("foo", 1);
emitter.Emit("foo", 2);
emitter.Emit("foo", 3);
emitter.Emit("bar", 1);
var expected = new Object[] {"one", 1};
Assert.Equal(expected, calls.ToArray());
}
public class TestListener3 : IListener
{
private readonly List<object> _calls;
public TestListener3(List<object> calls)
{
this._calls = calls;
}
public void Call(params object[] args)
{
_calls.Add("one");
}
public int CompareTo(IListener other)
{
return this.GetId().CompareTo(other.GetId());
}
public int GetId()
{
return 0;
}
}
public class TestListener4 : IListener
{
private readonly List<object> _calls;
public TestListener4(List<object> calls)
{
this._calls = calls;
}
public void Call(params object[] args)
{
_calls.Add("two");
}
public int CompareTo(IListener other)
{
return this.GetId().CompareTo(other.GetId());
}
public int GetId()
{
return 0;
}
}
[Fact]
public void Off()
{
LogManager.SetupLogManager();
var log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod());
log.Info("Start");
var emitter = new Emitter();
var calls = new List<object>();
var listener3 = new TestListener3(calls);
emitter.On("foo", listener3);
var listener4 = new TestListener4(calls);
emitter.On("foo", listener4);
emitter.Off("foo", listener4);
emitter.Emit("foo");
var expected = new Object[] {"one"};
Assert.Equal(expected, calls.ToArray());
}
[Fact]
public void OffWithOnce()
{
LogManager.SetupLogManager();
var log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod());
log.Info("Start");
var emitter = new Emitter();
var calls = new List<object>();
var listener3 = new TestListener3(calls);
emitter.Once("foo", listener3);
emitter.Off("foo", listener3);
emitter.Emit("foo");
var expected = new Object[] {};
Assert.Equal(expected, calls.ToArray());
}
public class TestListener5 : IListener
{
private readonly List<bool> _called;
public TestListener5(List<bool> called)
{
this._called = called;
}
public void Call(params object[] args)
{
this._called[0] = true;
}
public int CompareTo(IListener other)
{
return this.GetId().CompareTo(other.GetId());
}
public int GetId()
{
return 0;
}
}
public class TestListener6 : IListener
{
private readonly Emitter _emitter;
private readonly IListener _bListener;
public TestListener6(Emitter emitter, IListener bListener)
{
this._emitter = emitter;
this._bListener = bListener;
}
public void Call(params object[] args)
{
_emitter.Off("tobi", _bListener);
}
public int CompareTo(IListener other)
{
return this.GetId().CompareTo(other.GetId());
}
public int GetId()
{
return 0;
}
}
[Fact]
public void OffWhenCalledfromEvent()
{
LogManager.SetupLogManager();
var log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod());
log.Info("Start");
var emitter = new Emitter();
var called = new List<bool>() {false};
var listener5 = new TestListener5(called);
var listener6 = new TestListener6(emitter, listener5);
emitter.On("tobi", listener6);
emitter.Once("tobi", listener5);
emitter.Emit("tobi");
Assert.True(called[0]);
called[0] = false;
emitter.Emit("tobi");
Assert.False(called[0]);
}
[Fact]
public void OffEvent()
{
LogManager.SetupLogManager();
var log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod());
log.Info("Start");
var emitter = new Emitter();
var calls = new List<object>();
var listener3 = new TestListener3(calls);
emitter.On("foo", listener3);
var listener4 = new TestListener4(calls);
emitter.On("foo", listener3);
emitter.On("foo", listener4);
emitter.Off("foo");
emitter.Emit("foo");
emitter.Emit("foo");
var expected = new Object[] {};
Assert.Equal(expected, calls.ToArray());
}
[Fact]
public void OffAll()
{
LogManager.SetupLogManager();
var log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod());
log.Info("Start");
var emitter = new Emitter();
var calls = new List<object>();
var listener3 = new TestListener3(calls);
var listener4 = new TestListener4(calls);
emitter.On("foo", listener3);
emitter.On("bar", listener4);
emitter.Emit("foo");
emitter.Emit("bar");
emitter.Off();
emitter.Emit("foo");
emitter.Emit("bar");
var expected = new Object[] {"one", "two"};
Assert.Equal(expected, calls.ToArray());
}
[Fact]
public void Listeners()
{
LogManager.SetupLogManager();
var log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod());
log.Info("Start");
var emitter = new Emitter();
var calls = new List<object>();
var listener3 = new TestListener3(calls);
emitter.On("foo", listener3);
var expected = new IListener[] {listener3};
Assert.Equal(expected, emitter.Listeners("foo").ToArray());
}
[Fact]
public void ListenersWithoutHandlers()
{
LogManager.SetupLogManager();
var emitter = new Emitter();
var expected = new IListener[] {};
Assert.Equal(expected, emitter.Listeners("foo").ToArray());
}
[Fact]
public void HasListeners()
{
LogManager.SetupLogManager();
var log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod());
log.Info("Start");
var emitter = new Emitter();
var calls = new List<object>();
Assert.False(emitter.HasListeners("foo"));
var listener3 = new TestListener3(calls);
emitter.On("foo", listener3);
Assert.True(emitter.HasListeners("foo"));
}
[Fact]
public void HasListenersWithoutHandlers()
{
LogManager.SetupLogManager();
var log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod());
log.Info("Start");
var emitter = new Emitter();
Assert.False(emitter.HasListeners("foo"));
}
}
}

View File

@@ -0,0 +1,96 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{BA788BBE-0FE8-4C2F-8A02-457A5E9E2703}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>EngineIoClientDotNet.Tests.net35</RootNamespace>
<AssemblyName>EngineIoClientDotNet.Tests.net35</AssemblyName>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\EngineIoClientDotNet.net35\packages\Newtonsoft.Json.9.0.1\lib\net35\Newtonsoft.Json.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="SuperSocket.ClientEngine, Version=0.9.0.0, Culture=neutral, PublicKeyToken=ee9af13f57f00acc, processorArchitecture=MSIL">
<HintPath>..\EngineIoClientDotNet.net35\packages\SuperSocket.ClientEngine.Core.0.9.0\lib\net35-client\SuperSocket.ClientEngine.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Threading.Tasks.NET35, Version=3.0.2.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\EngineIoClientDotNet.net35\packages\System.Threading.Tasks.Unofficial.3.1\lib\net35\System.Threading.Tasks.NET35.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
<Reference Include="WebSocket4Net, Version=0.15.1.10, Culture=neutral, PublicKeyToken=eb4e154b696bf72a, processorArchitecture=MSIL">
<HintPath>..\EngineIoClientDotNet.net35\packages\WebSocket4Net.0.15.1\lib\net35\WebSocket4Net.dll</HintPath>
</Reference>
<Reference Include="xunit, Version=1.9.2.1705, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL">
<HintPath>..\EngineIoClientDotNet.net35\packages\xunit.1.9.2\lib\net20\xunit.dll</HintPath>
<Private>True</Private>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="ClientTests\BinaryPollingTest.cs" />
<Compile Include="ClientTests\BinaryWebSocketTest.cs" />
<Compile Include="ClientTests\Connection.cs" />
<Compile Include="ClientTests\ConnectionConstants.cs" />
<Compile Include="ClientTests\ConnectionTest.cs" />
<Compile Include="ClientTests\HandshakeDataTests.cs" />
<Compile Include="ClientTests\ServerConnectionTest.cs" />
<Compile Include="ClientTests\SocketTest.cs" />
<Compile Include="ClientTests\SSLServerConnectionTest.cs" />
<Compile Include="ClientTests\TransportTest.cs" />
<Compile Include="ClientTests\UsageTest.cs" />
<Compile Include="ComponentEmitterTests\EmitterTests.cs" />
<Compile Include="ModulesTests\ParseQSTests.cs" />
<Compile Include="ModulesTests\UTF8Tests.cs" />
<Compile Include="ParserTests\DecodeTests.cs" />
<Compile Include="ParserTests\TestsParser.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
<None Include="packages.config" />
</ItemGroup>
<ItemGroup />
<ItemGroup>
<ProjectReference Include="..\EngineIoClientDotNet.net35\EngineIoClientDotNet.net35.csproj">
<Project>{568d67d0-3253-4601-9b04-7730a9ec5cc0}</Project>
<Name>EngineIoClientDotNet.net35</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@@ -0,0 +1,68 @@

using System.Collections.Concurrent;
using Quobject.EngineIoClientDotNet.Modules;
using System.Collections.Generic;
using Xunit;
namespace Quobject.EngineIoClientDotNet_Tests.ModulesTests
{
public class ParseQsTests
{
//should parse a querystring and return an object
[Fact]
public void Decode()
{
LogManager.SetupLogManager();
var log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod());
log.Info("Start");
// Single assignment
var queryObj = ParseQS.Decode("foo=bar");
Assert.Equal("bar", queryObj["foo"]);
// Multiple assignments
queryObj = ParseQS.Decode("france=grenoble&germany=mannheim");
Assert.Equal("grenoble", queryObj["france"]);
Assert.Equal("mannheim", queryObj["germany"]);
// Assignments containing non-alphanumeric characters
queryObj = ParseQS.Decode("india=new%20delhi");
Assert.Equal("new delhi", queryObj["india"]);
}
//should construct a query string from an object'
[Fact]
public void Encode()
{
LogManager.SetupLogManager();
var log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod());
log.Info("Start");
//Dictionary<string, string> obj;
//obj = new Dictionary<string, string> {{"a", "b"}};
//var imObj = ImmutableDictionary.Create<string, string>().AddRange(obj);
var imObj = new ConcurrentDictionary<string, string>();
imObj.TryAdd("a","b");
Assert.Equal("a=b", ParseQS.Encode(imObj));
//obj = new Dictionary<string, string> {{"a", "b"}, {"c", "d"}};
//imObj = ImmutableDictionary.Create<string, string>().AddRange(obj);
imObj = new ConcurrentDictionary<string, string>();
imObj.TryAdd("a", "b");
imObj.TryAdd("c", "d");
Assert.Equal("a=b&c=d", ParseQS.Encode(imObj));
//obj = new Dictionary<string, string> {{"a", "b"}, {"c", "tobi rocks"}};
//imObj = ImmutableDictionary.Create<string, string>().AddRange(obj);
imObj = new ConcurrentDictionary<string, string>();
imObj.TryAdd("a", "b");
imObj.TryAdd("c", "tobi rocks");
Assert.Equal("a=b&c=tobi%20rocks", ParseQS.Encode(imObj));
}
}
}

View File

@@ -0,0 +1,144 @@
using Quobject.EngineIoClientDotNet.Modules;
using System;
using Xunit;
namespace Quobject.EngineIoClientDotNet_Tests.ModulesTests
{
public class Utf8Tests
{
private static readonly Data[] DATA = new Data[]
{
// 1-byte
new Data(0x0000, "\x00", "\x00"),
new Data(0x005c, "\u005C\u005C", "\u005C\u005C"), // = backslash
new Data(0x007f, "\u007F", "\u007F"),
// 2-byte
new Data(0x0080, "\u0080", "\u00C2\u0080"),
new Data(0x05CA, "\u05CA", "\u00D7\u008A"),
new Data(0x07FF, "\u07FF", "\u00DF\u00BF"),
// 3-byte
new Data(0x0800, "\u0800", "\u00E0\u00A0\u0080"),
new Data(0x2C3C, "\u2C3C", "\u00E2\u00B0\u00BC"),
new Data(0x07FF, "\uFFFF", "\u00EF\u00BF\u00BF"),
// unmatched surrogate halves
// high surrogates: 0xD800 to 0xDBFF
new Data(0xD800, "\uD800", "\u00ED\u00A0\u0080"),
new Data("High surrogate followed by another high surrogate",
"\uD800\uD800", "\u00ED\u00A0\u0080\u00ED\u00A0\u0080"),
new Data("High surrogate followed by a symbol that is not a surrogate",
"\uD800A", "\u00ED\u00A0\u0080A"),
new Data(
"Unmatched high surrogate, followed by a surrogate pair, followed by an unmatched high surrogate",
"\uD800\uD834\uDF06\uD800", "\u00ED\u00A0\u0080\u00F0\u009D\u008C\u0086\u00ED\u00A0\u0080"),
new Data(0xD9AF, "\uD9AF", "\u00ED\u00A6\u00AF"),
new Data(0xDBFF, "\uDBFF", "\u00ED\u00AF\u00BF"),
// low surrogates: 0xDC00 to 0xDFFF
new Data(0xDC00, "\uDC00", "\u00ED\u00B0\u0080"),
new Data("Low surrogate followed by another low surrogate",
"\uDC00\uDC00", "\u00ED\u00B0\u0080\u00ED\u00B0\u0080"),
new Data("Low surrogate followed by a symbol that is not a surrogate",
"\uDC00A", "\u00ED\u00B0\u0080A"),
new Data(
"Unmatched low surrogate, followed by a surrogate pair, followed by an unmatched low surrogate",
"\uDC00\uD834\uDF06\uDC00", "\u00ED\u00B0\u0080\u00F0\u009D\u008C\u0086\u00ED\u00B0\u0080"),
new Data(0xDEEE, "\uDEEE", "\u00ED\u00BB\u00AE"),
new Data(0xDFFF, "\uDFFF", "\u00ED\u00BF\u00BF"),
// 4-byte
new Data(0x010000, "\uD800\uDC00", "\u00F0\u0090\u0080\u0080"),
new Data(0x01D306, "\uD834\uDF06", "\u00F0\u009D\u008C\u0086"),
new Data(0x010FFF, "\uDBFF\uDFFF", "\u00F4\u008F\u00BF\u00BF"),
};
//
[Fact]
public void EncodeAndDecode()
{
LogManager.SetupLogManager();
var log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod());
log.Info("Start");
foreach (var data in DATA)
{
data.Test();
}
}
private class Data
{
private readonly int _codePoint = -1;
private String Description { get; set; }
private String Decoded { get; set; }
private String Encoded { get; set; }
public Data(int codePoint, String decoded, String encoded)
{
this._codePoint = codePoint;
this.Decoded = decoded;
this.Encoded = encoded;
}
public Data(String description, String decoded, String encoded)
{
this.Description = description;
this.Decoded = decoded;
this.Encoded = encoded;
}
public void Test()
{
EncodingTest();
DecodingTest();
ExceptionTest();
}
private void EncodingTest()
{
var value = UTF8.Encode(Decoded);
Assert.Equal(Encoded, value);
}
private void DecodingTest()
{
Assert.Equal(Decoded, UTF8.Decode(Encoded));
}
private void ExceptionTest()
{
Assert.Throws<UTF8Exception>(
delegate
{
UTF8.Decode("\uFFFF");
});
Assert.Throws<UTF8Exception>(
delegate
{
UTF8.Decode("\xE9\x00\x00");
});
Assert.Throws<UTF8Exception>(
delegate
{
UTF8.Decode("\xC2\uFFFF");
});
Assert.Throws<UTF8Exception>(
delegate
{
UTF8.Decode("\xF0\x9D");
});
}
private string Reason
{
get { return Description ?? "U+" + _codePoint.ToString("X4").ToUpper(); }
}
}
}
}

View File

@@ -0,0 +1,98 @@
using Quobject.EngineIoClientDotNet.Modules;
using Quobject.EngineIoClientDotNet.Parser;
using Xunit;
namespace Quobject.EngineIoClientDotNet_Tests.ParserTests
{
public class DecodeTests
{
private const string PARSER_ERROR = "parser error";
[Fact]
public void DecodeBadFormat()
{
LogManager.SetupLogManager();
var log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod());
log.Info("Start");
Packet p = Parser.DecodePacket(":::");
Assert.Equal(Packet.ERROR, p.Type);
Assert.Equal(PARSER_ERROR, p.Data);
}
[Fact]
public void DecodeInexistingTypes()
{
LogManager.SetupLogManager();
var log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod());
log.Info("Start");
Packet p = Parser.DecodePacket("94103");
Assert.Equal(Packet.ERROR, p.Type);
Assert.Equal(PARSER_ERROR, p.Data);
}
[Fact]
public void DecodeInvalidUTF8()
{
LogManager.SetupLogManager();
var log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod());
log.Info("Start");
Packet p = Parser.DecodePacket("4\uffff", true);
Assert.Equal(Packet.ERROR, p.Type);
Assert.Equal(PARSER_ERROR, p.Data);
}
public class DecodePayloadBadFormat_DecodeCallback : IDecodePayloadCallback
{
public bool Call(Packet packet, int index, int total)
{
var isLast = index + 1 == total;
Assert.True(isLast);
Assert.Equal(Packet.ERROR, packet.Type);
Assert.Equal(PARSER_ERROR, packet.Data);
return true;
}
}
[Fact]
public void EncodeAndDecodeEmptyPayloads()
{
LogManager.SetupLogManager();
var log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod());
log.Info("Start");
Packet.DecodePayload("1!", new DecodePayloadBadFormat_DecodeCallback());
Packet.DecodePayload("", new DecodePayloadBadFormat_DecodeCallback());
Packet.DecodePayload("))", new DecodePayloadBadFormat_DecodeCallback());
}
[Fact]
public void DecodePayloadBadPacketFormat()
{
LogManager.SetupLogManager();
var log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod());
log.Info("Start");
Packet.DecodePayload("3:99", new DecodePayloadBadFormat_DecodeCallback());
Packet.DecodePayload("1:aa", new DecodePayloadBadFormat_DecodeCallback());
Packet.DecodePayload("1:a2:b", new DecodePayloadBadFormat_DecodeCallback());
}
[Fact]
public void DecodePayloadInvalidUTF8()
{
LogManager.SetupLogManager();
var log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod());
log.Info("Start");
Packet.DecodePayload("2:4\uffff", new DecodePayloadBadFormat_DecodeCallback());
}
}
}

View File

@@ -0,0 +1,477 @@
using Quobject.EngineIoClientDotNet.Modules;
using Quobject.EngineIoClientDotNet.Parser;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using Xunit;
namespace Quobject.EngineIoClientDotNet_Tests.ParserTests
{
public class TestsParser
{
public interface IPacketTest
{
Packet GetPacket();
}
[Fact]
public void EncodeTests()
{
LogManager.SetupLogManager();
var log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod());
log.Info("Start");
var testList = new List<IPacketTest>()
{
new EncodeAsStringCallback(),
new DecodeAsPacketCallback(),
new NoDataCallback(),
new EncodeOpenPacket(),
new EncodeClosePacket(),
new EncodePingPacket(),
new EncodePongPacket(),
new EncodeMessagePacket(),
new EncodeUTF8SpecialCharsPacket(),
new EncodeUpgradePacket(),
new EncodeFormat1(),
new EncodeFormat2(),
};
foreach (var test in testList)
{
Parser.EncodePacket(test.GetPacket(), (IEncodeCallback) test);
}
}
public class EncodeAsStringCallback : IEncodeCallback, IPacketTest
{
public void Call(object data)
{
Assert.IsType<string>(data);
}
public Packet GetPacket()
{
return new Packet(Packet.MESSAGE, "test");
}
}
public class DecodeAsPacketCallback : IEncodeCallback, IPacketTest
{
public void Call(object data)
{
Assert.IsType<Packet>(Parser.DecodePacket((string) data));
}
public Packet GetPacket()
{
return new Packet(Packet.MESSAGE, "test");
}
}
public class NoDataCallback : IEncodeCallback, IPacketTest
{
public void Call(object data)
{
Packet p = Parser.DecodePacket((string) data);
Assert.Equal(Packet.MESSAGE, p.Type);
Assert.Null(p.Data);
}
public Packet GetPacket()
{
return new Packet(Packet.MESSAGE);
}
}
public class EncodeOpenPacket : IEncodeCallback, IPacketTest
{
private static string Json = "{\"some\":\"json\"}";
public void Call(object data)
{
Packet p = Parser.DecodePacket((string) data);
Assert.Equal(Packet.OPEN, p.Type);
Assert.Equal(Json, p.Data);
}
public Packet GetPacket()
{
return new Packet(Packet.OPEN, Json);
}
}
public class EncodeClosePacket : IEncodeCallback, IPacketTest
{
public void Call(object data)
{
Packet p = Parser.DecodePacket((string) data);
Assert.Equal(Packet.CLOSE, p.Type);
}
public Packet GetPacket()
{
return new Packet(Packet.CLOSE);
}
}
public class EncodePingPacket : IEncodeCallback, IPacketTest
{
public void Call(object data)
{
Packet p = Parser.DecodePacket((string) data);
Assert.Equal(Packet.PING, p.Type);
Assert.Equal("1", p.Data);
}
public Packet GetPacket()
{
return new Packet(Packet.PING, "1");
}
}
public class EncodePongPacket : IEncodeCallback, IPacketTest
{
public void Call(object data)
{
Packet p = Parser.DecodePacket((string) data);
Assert.Equal(Packet.PONG, p.Type);
Assert.Equal("1", p.Data);
}
public Packet GetPacket()
{
return new Packet(Packet.PONG, "1");
}
}
public class EncodeMessagePacket : IEncodeCallback, IPacketTest
{
public void Call(object data)
{
Packet p = Parser.DecodePacket((string) data);
Assert.Equal(Packet.MESSAGE, p.Type);
Assert.Equal("aaa", p.Data);
}
public Packet GetPacket()
{
return new Packet(Packet.MESSAGE, "aaa");
}
}
public class EncodeUTF8SpecialCharsPacket : IEncodeCallback, IPacketTest
{
public void Call(object data)
{
Packet p = Parser.DecodePacket((string) data);
Assert.Equal(Packet.MESSAGE, p.Type);
Assert.Equal("utf8 — string", p.Data);
}
public Packet GetPacket()
{
return new Packet(Packet.MESSAGE, "utf8 — string");
}
}
public class EncodeUpgradePacket : IEncodeCallback, IPacketTest
{
public void Call(object data)
{
Packet p = Parser.DecodePacket((string) data);
Assert.Equal(Packet.UPGRADE, p.Type);
}
public Packet GetPacket()
{
return new Packet(Packet.UPGRADE);
}
}
public class EncodeFormat1 : IEncodeCallback, IPacketTest
{
public void Call(object data)
{
var dataString = data as string;
var r = new Regex(@"[0-9]", RegexOptions.IgnoreCase);
Assert.True(r.Match(dataString).Success);
}
public Packet GetPacket()
{
return new Packet(Packet.MESSAGE);
}
}
public class EncodeFormat2 : IEncodeCallback, IPacketTest
{
public void Call(object data)
{
var dataString = data as string;
Assert.Equal("4test", dataString);
}
public Packet GetPacket()
{
return new Packet(Packet.MESSAGE, "test");
}
}
public class EncodePayloadsCallback : IEncodeCallback
{
public void Call(object data)
{
Assert.IsType<byte[]>(data);
}
}
[Fact]
public void EncodePayloads()
{
LogManager.SetupLogManager();
var log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod());
log.Info("Start");
var packets = new Packet[] {new Packet(Packet.PING), new Packet(Packet.PONG),};
Parser.EncodePayload(packets, new EncodePayloadsCallback());
}
public class EncodeAndDecodePayloads_EncodeCallback : IEncodeCallback
{
public void Call(object data)
{
Parser.DecodePayload((byte[]) data, new EncodeAndDecodePayloads_DecodeCallback());
}
public class EncodeAndDecodePayloads_DecodeCallback : IDecodePayloadCallback
{
public bool Call(Packet packet, int index, int total)
{
bool isLast = index + 1 == total;
Assert.True(isLast);
return true;
}
}
}
[Fact]
public void EncodeAndDecodePayloads()
{
LogManager.SetupLogManager();
var log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod());
log.Info("Start");
var packets = new Packet[] {new Packet(Packet.MESSAGE, "a"),};
Parser.EncodePayload(packets, new EncodeAndDecodePayloads_EncodeCallback());
}
public class EncodeAndDecodePayloads_EncodeCallback2 : IEncodeCallback
{
public void Call(object data)
{
Parser.DecodePayload((byte[]) data, new EncodeAndDecodePayloads_DecodeCallback2());
}
public class EncodeAndDecodePayloads_DecodeCallback2 : IDecodePayloadCallback
{
public bool Call(Packet packet, int index, int total)
{
var isLast = index + 1 == total;
Assert.Equal(isLast ? Packet.PING : Packet.MESSAGE, packet.Type);
return true;
}
}
}
[Fact]
public void EncodeAndDecodePayloads2()
{
LogManager.SetupLogManager();
var log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod());
log.Info("Start");
var packets = new Packet[] {new Packet(Packet.MESSAGE, "a"), new Packet(Packet.PING),};
Parser.EncodePayload(packets, new EncodeAndDecodePayloads_EncodeCallback2());
}
public class EncodeAndDecodeEmptyPayloads_EncodeCallback : IEncodeCallback
{
public void Call(object data)
{
Parser.DecodePayload((byte[]) data, new EncodeAndDecodeEmptyPayloads_DecodeCallback());
}
public class EncodeAndDecodeEmptyPayloads_DecodeCallback : IDecodePayloadCallback
{
public bool Call(Packet packet, int index, int total)
{
Assert.Equal(Packet.OPEN, packet.Type);
var isLast = index + 2 == total;
Assert.True(isLast);
return true;
}
}
}
[Fact]
public void EncodeAndDecodeEmptyPayloads()
{
LogManager.SetupLogManager();
var log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod());
log.Info("Start");
var packets = new Packet[] {};
Parser.EncodePayload(packets, new EncodeAndDecodeEmptyPayloads_EncodeCallback());
}
public class EncodeAndDecodeBinaryContents_EncodeCallback : IEncodeCallback
{
public void Call(object data)
{
Parser.DecodePayload((byte[]) data, new EncodeAndDecodeBinaryContents_DecodeCallback());
}
public class EncodeAndDecodeBinaryContents_DecodeCallback : IDecodePayloadCallback
{
public bool Call(Packet packet, int index, int total)
{
Assert.Equal(Packet.MESSAGE, packet.Type);
var isLast = index + 1 == total;
if (!isLast)
{
Assert.Equal(FirstBuffer(), packet.Data);
}
else
{
Assert.Equal(SecondBuffer(), packet.Data);
}
return true;
}
}
}
[Fact]
public void EncodeAndDecodeBinaryContents()
{
LogManager.SetupLogManager();
var log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod());
log.Info("Start");
var firstBuffer = FirstBuffer();
var secondBuffer = SecondBuffer();
var packets = new Packet[]
{new Packet(Packet.MESSAGE, firstBuffer), new Packet(Packet.MESSAGE, secondBuffer)};
Parser.EncodePayload(packets, new EncodeAndDecodeBinaryContents_EncodeCallback());
}
private static byte[] SecondBuffer()
{
var secondBuffer = new byte[4];
for (int i = 0; i < secondBuffer.Length; i++)
{
secondBuffer[i] = (byte) (5 + i);
}
return secondBuffer;
}
private static byte[] FirstBuffer()
{
var firstBuffer = new byte[5];
for (int i = 0; i < firstBuffer.Length; i++)
{
firstBuffer[i] = (byte) i;
}
return firstBuffer;
}
private static byte[] ThirdBuffer()
{
var result = new byte[123];
for (int i = 0; i < result.Length; i++)
{
result[i] = (byte) i;
}
return result;
}
public class EncodeMixedBinaryAndStringContents_EncodeCallback : IEncodeCallback
{
public void Call(object data)
{
Parser.DecodePayload((byte[]) data, new EncodeMixedBinaryAndStringContents_DecodeCallback());
}
public class EncodeMixedBinaryAndStringContents_DecodeCallback : IDecodePayloadCallback
{
public bool Call(Packet packet, int index, int total)
{
if (index == 0)
{
Assert.Equal(Packet.MESSAGE, packet.Type);
Assert.Equal(ThirdBuffer(), packet.Data);
}
else if (index == 1)
{
Assert.Equal(Packet.MESSAGE, packet.Type);
Assert.Equal("hello", packet.Data);
}
else
{
Assert.Equal(Packet.CLOSE, packet.Type);
}
return true;
}
}
}
[Fact]
public void EncodeMixedBinaryAndStringContents()
{
LogManager.SetupLogManager();
var log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod());
log.Info("Start");
var packets = new Packet[]
{
new Packet(Packet.MESSAGE, ThirdBuffer()),
new Packet(Packet.MESSAGE, "hello"),
new Packet(Packet.CLOSE),
};
Parser.EncodePayload(packets, new EncodeMixedBinaryAndStringContents_EncodeCallback());
}
}
}

View File

@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("EngineIoClientDotNet.Tests2.net35")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("EngineIoClientDotNet.Tests2.net35")]
[assembly: AssemblyCopyright("Copyright © 2017")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("ba788bbe-0fe8-4c2f-8a02-457a5e9e2703")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="SuperSocket.ClientEngine" publicKeyToken="ee9af13f57f00acc" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-0.9.0.0" newVersion="0.9.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="more.xunit.runner.visualstudio" version="2.3.1" targetFramework="net35" developmentDependency="true" />
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="net35" />
<package id="SuperSocket.ClientEngine.Core" version="0.9.0" targetFramework="net35" />
<package id="System.Threading.Tasks.Unofficial" version="3.1" targetFramework="net35" />
<package id="WebSocket4Net" version="0.15.1" targetFramework="net35" />
<package id="xunit" version="1.9.2" targetFramework="net35" />
</packages>

View File

@@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Quobject.EngineIoClientDotNet_Tests.ClientTests
{
public static class ConnectionConstants
{
public static int PORT = 80;
public static string HOSTNAME = "testme.quobject.com";
public static int SSL_PORT = 443;
public static readonly int TIMEOUT = 300000;
}
}

View File

@@ -0,0 +1,157 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\EngineIoClientDotNet.net40\packages\xunit.core.2.3.0-beta3-build3705\build\xunit.core.props" Condition="Exists('..\EngineIoClientDotNet.net40\packages\xunit.core.2.3.0-beta3-build3705\build\xunit.core.props')" />
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{DF3284AF-2FE7-4855-8111-38835A703564}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>EngineIoClientDotNet.Tests.net40</RootNamespace>
<AssemblyName>EngineIoClientDotNet.Tests.net40</AssemblyName>
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<ItemGroup>
<Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\EngineIoClientDotNet.net40\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="SuperSocket.ClientEngine, Version=0.9.0.0, Culture=neutral, PublicKeyToken=ee9af13f57f00acc, processorArchitecture=MSIL">
<HintPath>..\EngineIoClientDotNet.net40\packages\SuperSocket.ClientEngine.Core.0.9.0\lib\net45\SuperSocket.ClientEngine.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
<Reference Include="WebSocket4Net, Version=0.15.1.10, Culture=neutral, PublicKeyToken=eb4e154b696bf72a, processorArchitecture=MSIL">
<HintPath>..\EngineIoClientDotNet.net40\packages\WebSocket4Net.0.15.1\lib\net45\WebSocket4Net.dll</HintPath>
</Reference>
<Reference Include="xunit.abstractions, Version=2.0.0.0, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL">
<HintPath>..\EngineIoClientDotNet.net40\packages\xunit.abstractions.2.0.1\lib\net35\xunit.abstractions.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="xunit.assert, Version=2.3.0.3705, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL">
<HintPath>..\EngineIoClientDotNet.net40\packages\xunit.assert.2.3.0-beta3-build3705\lib\netstandard1.1\xunit.assert.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="xunit.core, Version=2.3.0.3705, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL">
<HintPath>..\EngineIoClientDotNet.net40\packages\xunit.extensibility.core.2.3.0-beta3-build3705\lib\netstandard1.1\xunit.core.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="xunit.execution.desktop, Version=2.3.0.3705, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL">
<HintPath>..\EngineIoClientDotNet.net40\packages\xunit.extensibility.execution.2.3.0-beta3-build3705\lib\net452\xunit.execution.desktop.dll</HintPath>
<Private>True</Private>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="..\EngineIoClientDotNet.Tests.net35\ClientTests\BinaryPollingTest.cs">
<Link>ClientTests\BinaryPollingTest.cs</Link>
</Compile>
<Compile Include="..\EngineIoClientDotNet.Tests.net35\ClientTests\BinaryWebSocketTest.cs">
<Link>ClientTests\BinaryWebSocketTest.cs</Link>
</Compile>
<Compile Include="..\EngineIoClientDotNet.Tests.net35\ClientTests\Connection.cs">
<Link>ClientTests\Connection.cs</Link>
</Compile>
<Compile Include="..\EngineIoClientDotNet.Tests.net35\ClientTests\ConnectionTest.cs">
<Link>ClientTests\ConnectionTest.cs</Link>
</Compile>
<Compile Include="..\EngineIoClientDotNet.Tests.net35\ClientTests\HandshakeDataTests.cs">
<Link>ClientTests\HandshakeDataTests.cs</Link>
</Compile>
<Compile Include="..\EngineIoClientDotNet.Tests.net35\ClientTests\ServerConnectionTest.cs">
<Link>ClientTests\ServerConnectionTest.cs</Link>
</Compile>
<Compile Include="..\EngineIoClientDotNet.Tests.net35\ClientTests\SocketTest.cs">
<Link>ClientTests\SocketTest.cs</Link>
</Compile>
<Compile Include="..\EngineIoClientDotNet.Tests.net35\ClientTests\SSLServerConnectionTest.cs">
<Link>ClientTests\SSLServerConnectionTest.cs</Link>
</Compile>
<Compile Include="..\EngineIoClientDotNet.Tests.net35\ClientTests\TransportTest.cs">
<Link>ClientTests\TransportTest.cs</Link>
</Compile>
<Compile Include="..\EngineIoClientDotNet.Tests.net35\ClientTests\UsageTest.cs">
<Link>ClientTests\UsageTest.cs</Link>
</Compile>
<Compile Include="..\EngineIoClientDotNet.Tests.net35\ComponentEmitterTests\EmitterTests.cs">
<Link>ComponentEmitterTests\EmitterTests.cs</Link>
</Compile>
<Compile Include="..\EngineIoClientDotNet.Tests.net35\ModulesTests\ParseQSTests.cs">
<Link>ModulesTests\ParseQSTests.cs</Link>
</Compile>
<Compile Include="..\EngineIoClientDotNet.Tests.net35\ModulesTests\UTF8Tests.cs">
<Link>ModulesTests\UTF8Tests.cs</Link>
</Compile>
<Compile Include="..\EngineIoClientDotNet.Tests.net35\ParserTests\DecodeTests.cs">
<Link>ParserTests\DecodeTests.cs</Link>
</Compile>
<Compile Include="..\EngineIoClientDotNet.Tests.net35\ParserTests\TestsParser.cs">
<Link>ParserTests\TestsParser.cs</Link>
</Compile>
<Compile Include="ClientTests\ConnectionConstants.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\EngineIoClientDotNet.net40\EngineIoClientDotNet.net40.csproj">
<Project>{833dbca1-0b01-4477-9937-a8e50e426ee5}</Project>
<Name>EngineIoClientDotNet.net40</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
<None Include="config.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
</ItemGroup>
<ItemGroup>
<Analyzer Include="..\EngineIoClientDotNet.net40\packages\xunit.analyzers.0.3.0\analyzers\dotnet\cs\xunit.analyzers.dll" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\EngineIoClientDotNet.net40\packages\xunit.core.2.3.0-beta3-build3705\build\xunit.core.props')" Text="$([System.String]::Format('$(ErrorText)', '..\EngineIoClientDotNet.net40\packages\xunit.core.2.3.0-beta3-build3705\build\xunit.core.props'))" />
<Error Condition="!Exists('..\EngineIoClientDotNet.net40\packages\xunit.core.2.3.0-beta3-build3705\build\xunit.core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\EngineIoClientDotNet.net40\packages\xunit.core.2.3.0-beta3-build3705\build\xunit.core.targets'))" />
</Target>
<Import Project="..\EngineIoClientDotNet.net40\packages\xunit.core.2.3.0-beta3-build3705\build\xunit.core.targets" Condition="Exists('..\EngineIoClientDotNet.net40\packages\xunit.core.2.3.0-beta3-build3705\build\xunit.core.targets')" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("EngineIoClientDotNet.Tests.net40")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("EngineIoClientDotNet.Tests.net40")]
[assembly: AssemblyCopyright("Copyright © 2015")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("75432de3-510e-4d31-ba47-b25eaa997026")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="SuperSocket.ClientEngine" publicKeyToken="ee9af13f57f00acc" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-0.9.0.0" newVersion="0.9.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

View File

@@ -0,0 +1,19 @@
{
"version":"0.9.23",
"server":{
"port":80,
"ssl_port":443,
"hostname":"testme.quobject.com"
},
"win":{
"powershell":"C:/WINDOWS/System32/WindowsPowerShell/v1.0/powershell.exe",
"msbuild": "C:/Windows/Microsoft.NET/Framework/v4.0.30319/msbuild.exe",
// "xunit_path":"C:/ProgramData/chocolatey/bin",
"xunit_path":"C:/Development/quobject.visualstudio.com/EngineIoClientDotNet/Src/EngineIoClientDotNet.net45/packages/xunit.runner.console.2.0.0/tools/",
"nuget":"C:/ProgramData/chocolatey/bin/NuGet.exe"
},
"linux":{
"msbuild":"xbuild",
"xunit_path":"/home/apollo/vendors/xunit"
}
}

View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="net452" />
<package id="SuperSocket.ClientEngine.Core" version="0.9.0" targetFramework="net452" />
<package id="WebSocket4Net" version="0.15.1" targetFramework="net452" />
<package id="xunit" version="2.3.0-beta3-build3705" targetFramework="net452" />
<package id="xunit.abstractions" version="2.0.1" targetFramework="net452" />
<package id="xunit.analyzers" version="0.3.0" targetFramework="net452" />
<package id="xunit.assert" version="2.3.0-beta3-build3705" targetFramework="net452" />
<package id="xunit.core" version="2.3.0-beta3-build3705" targetFramework="net452" />
<package id="xunit.extensibility.core" version="2.3.0-beta3-build3705" targetFramework="net452" />
<package id="xunit.extensibility.execution" version="2.3.0-beta3-build3705" targetFramework="net452" />
</packages>

View File

@@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Quobject.EngineIoClientDotNet_Tests.ClientTests
{
public static class ConnectionConstants
{
public static int PORT = 80;
public static string HOSTNAME = "testme.quobject.com";
public static int SSL_PORT = 443;
public static readonly int TIMEOUT = 300000;
}
}

View File

@@ -0,0 +1,159 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\EngineIoClientDotNet.net45\packages\xunit.runner.visualstudio.2.3.0-beta3-build3705\build\net20\xunit.runner.visualstudio.props" Condition="Exists('..\EngineIoClientDotNet.net45\packages\xunit.runner.visualstudio.2.3.0-beta3-build3705\build\net20\xunit.runner.visualstudio.props')" />
<Import Project="..\EngineIoClientDotNet.net45\packages\xunit.core.2.3.0-beta3-build3705\build\xunit.core.props" Condition="Exists('..\EngineIoClientDotNet.net45\packages\xunit.core.2.3.0-beta3-build3705\build\xunit.core.props')" />
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{BEFF0675-8A73-4012-9651-C253E06E0F87}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>EngineIoClientDotNet.Tests</RootNamespace>
<AssemblyName>EngineIoClientDotNet.Tests.net45</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\EngineIoClientDotNet.net45\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Collections.Immutable, Version=1.2.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\EngineIoClientDotNet.net45\packages\System.Collections.Immutable.1.4.0\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll</HintPath>
</Reference>
<Reference Include="System.ComponentModel.Composition" />
<Reference Include="System.Core" />
<Reference Include="System.IO.Compression" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Numerics" />
<Reference Include="System.Runtime.InteropServices.RuntimeInformation, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\EngineIoClientDotNet.net45\packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Xml" />
<Reference Include="System.Xml.Linq" />
<Reference Include="xunit.abstractions, Version=2.0.0.0, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL">
<HintPath>..\EngineIoClientDotNet.net45\packages\xunit.abstractions.2.0.1\lib\net35\xunit.abstractions.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="xunit.assert, Version=2.3.0.3705, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL">
<HintPath>..\EngineIoClientDotNet.net45\packages\xunit.assert.2.3.0-beta3-build3705\lib\netstandard1.1\xunit.assert.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="xunit.core, Version=2.3.0.3705, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL">
<HintPath>..\EngineIoClientDotNet.net45\packages\xunit.extensibility.core.2.3.0-beta3-build3705\lib\netstandard1.1\xunit.core.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="xunit.execution.dotnet, Version=2.3.0.3705, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL">
<HintPath>..\EngineIoClientDotNet.net45\packages\xunit.extensibility.execution.2.3.0-beta3-build3705\lib\netstandard1.1\xunit.execution.dotnet.dll</HintPath>
<Private>True</Private>
</Reference>
</ItemGroup>
<ItemGroup>
<Folder Include="ThreadTests\" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\EngineIoClientDotNet.net45\EngineIoClientDotNet.net45.csproj">
<Project>{842d8b13-daf3-4919-80a0-03efa3c17178}</Project>
<Name>EngineIoClientDotNet.net45</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Compile Include="..\EngineIoClientDotNet.Tests.mono\ClientTests\BinaryPollingTest.cs">
<Link>ClientTests\BinaryPollingTest.cs</Link>
</Compile>
<Compile Include="..\EngineIoClientDotNet.Tests.mono\ClientTests\BinaryWebSocketTest.cs">
<Link>ClientTests\BinaryWebSocketTest.cs</Link>
</Compile>
<Compile Include="..\EngineIoClientDotNet.Tests.mono\ClientTests\Connection.cs">
<Link>ClientTests\Connection.cs</Link>
</Compile>
<Compile Include="..\EngineIoClientDotNet.Tests.mono\ClientTests\ConnectionTest.cs">
<Link>ClientTests\ConnectionTest.cs</Link>
</Compile>
<Compile Include="..\EngineIoClientDotNet.Tests.mono\ClientTests\HandshakeDataTests.cs">
<Link>ClientTests\HandshakeDataTests.cs</Link>
</Compile>
<Compile Include="..\EngineIoClientDotNet.Tests.mono\ClientTests\ServerConnectionTest.cs">
<Link>ClientTests\ServerConnectionTest.cs</Link>
</Compile>
<Compile Include="..\EngineIoClientDotNet.Tests.mono\ClientTests\SocketTest.cs">
<Link>ClientTests\SocketTest.cs</Link>
</Compile>
<Compile Include="..\EngineIoClientDotNet.Tests.mono\ClientTests\SSLServerConnectionTest.cs">
<Link>ClientTests\SSLServerConnectionTest.cs</Link>
</Compile>
<Compile Include="..\EngineIoClientDotNet.Tests.mono\ClientTests\TransportTest.cs">
<Link>ClientTests\TransportTest.cs</Link>
</Compile>
<Compile Include="..\EngineIoClientDotNet.Tests.mono\ClientTests\UsageTest.cs">
<Link>ClientTests\UsageTest.cs</Link>
</Compile>
<Compile Include="..\EngineIoClientDotNet.Tests.mono\ComponentEmitterTests\EmitterTests.cs">
<Link>ComponentEmitterTests\EmitterTests.cs</Link>
</Compile>
<Compile Include="..\EngineIoClientDotNet.Tests.mono\ModulesTests\ParseQSTests.cs">
<Link>ModulesTests\ParseQSTests.cs</Link>
</Compile>
<Compile Include="..\EngineIoClientDotNet.Tests.mono\ModulesTests\UTF8Tests.cs">
<Link>ModulesTests\UTF8Tests.cs</Link>
</Compile>
<Compile Include="..\EngineIoClientDotNet.Tests.mono\ParserTests\DecodeTests.cs">
<Link>ParserTests\DecodeTests.cs</Link>
</Compile>
<Compile Include="..\EngineIoClientDotNet.Tests.mono\ParserTests\TestsParser.cs">
<Link>ParserTests\TestsParser.cs</Link>
</Compile>
<Compile Include="ClientTests\ConnectionConstants.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
</ItemGroup>
<ItemGroup>
<Analyzer Include="..\EngineIoClientDotNet.net45\packages\xunit.analyzers.0.5.0\analyzers\dotnet\cs\xunit.analyzers.dll" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\EngineIoClientDotNet.net45\packages\xunit.core.2.3.0-beta3-build3705\build\xunit.core.props')" Text="$([System.String]::Format('$(ErrorText)', '..\EngineIoClientDotNet.net45\packages\xunit.core.2.3.0-beta3-build3705\build\xunit.core.props'))" />
<Error Condition="!Exists('..\EngineIoClientDotNet.net45\packages\xunit.core.2.3.0-beta3-build3705\build\xunit.core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\EngineIoClientDotNet.net45\packages\xunit.core.2.3.0-beta3-build3705\build\xunit.core.targets'))" />
<Error Condition="!Exists('..\EngineIoClientDotNet.net45\packages\xunit.runner.visualstudio.2.3.0-beta3-build3705\build\net20\xunit.runner.visualstudio.props')" Text="$([System.String]::Format('$(ErrorText)', '..\EngineIoClientDotNet.net45\packages\xunit.runner.visualstudio.2.3.0-beta3-build3705\build\net20\xunit.runner.visualstudio.props'))" />
<Error Condition="!Exists('..\EngineIoClientDotNet.net45\packages\NETStandard.Library.2.0.0-preview2-25401-01\build\NETStandard.Library.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\EngineIoClientDotNet.net45\packages\NETStandard.Library.2.0.0-preview2-25401-01\build\NETStandard.Library.targets'))" />
</Target>
<Import Project="..\EngineIoClientDotNet.net45\packages\xunit.core.2.3.0-beta3-build3705\build\xunit.core.targets" Condition="Exists('..\EngineIoClientDotNet.net45\packages\xunit.core.2.3.0-beta3-build3705\build\xunit.core.targets')" />
<Import Project="..\EngineIoClientDotNet.net45\packages\NETStandard.Library.2.0.0-preview2-25401-01\build\NETStandard.Library.targets" Condition="Exists('..\EngineIoClientDotNet.net45\packages\NETStandard.Library.2.0.0-preview2-25401-01\build\NETStandard.Library.targets')" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@@ -0,0 +1,35 @@
using System.Reflection;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("EngineIoClientDotNet")]
[assembly: AssemblyDescription("Engine.IO Client Library for .Net")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Quobject Software")]
[assembly: AssemblyProduct("EngineIoClientDotNet")]
[assembly: AssemblyCopyright("Copyright © 2015")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("a95e75cd-35e6-4e88-9e22-631e3fd01546")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("0.9.19")]
[assembly: AssemblyFileVersion("0.9.19")]

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="SuperSocket.ClientEngine" publicKeyToken="ee9af13f57f00acc" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-0.9.0.0" newVersion="0.9.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

View File

@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.NETCore.Platforms" version="2.0.0-preview2-25405-01" targetFramework="net45" />
<package id="NETStandard.Library" version="2.0.0-preview2-25401-01" targetFramework="net45" />
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="net45" />
<package id="System.Collections" version="4.3.0" targetFramework="net45" />
<package id="System.Collections.Concurrent" version="4.3.0" targetFramework="net45" />
<package id="System.Collections.Immutable" version="1.4.0" targetFramework="net45" />
<package id="System.Diagnostics.Debug" version="4.3.0" targetFramework="net45" />
<package id="System.Diagnostics.Tools" version="4.3.0" targetFramework="net45" />
<package id="System.Diagnostics.Tracing" version="4.3.0" targetFramework="net45" />
<package id="System.Globalization" version="4.3.0" targetFramework="net45" />
<package id="System.IO" version="4.3.0" targetFramework="net45" />
<package id="System.IO.Compression" version="4.3.0" targetFramework="net45" />
<package id="System.Linq" version="4.3.0" targetFramework="net45" />
<package id="System.Linq.Expressions" version="4.3.0" targetFramework="net45" />
<package id="System.Net.Http" version="4.3.2" targetFramework="net45" />
<package id="System.Net.Primitives" version="4.3.0" targetFramework="net45" />
<package id="System.ObjectModel" version="4.3.0" targetFramework="net45" />
<package id="System.Reflection" version="4.3.0" targetFramework="net45" />
<package id="System.Reflection.Extensions" version="4.3.0" targetFramework="net45" />
<package id="System.Reflection.Primitives" version="4.3.0" targetFramework="net45" />
<package id="System.Resources.ResourceManager" version="4.3.0" targetFramework="net45" />
<package id="System.Runtime" version="4.3.0" targetFramework="net45" />
<package id="System.Runtime.Extensions" version="4.3.0" targetFramework="net45" />
<package id="System.Runtime.InteropServices" version="4.3.0" targetFramework="net45" />
<package id="System.Runtime.InteropServices.RuntimeInformation" version="4.3.0" targetFramework="net45" />
<package id="System.Runtime.Numerics" version="4.3.0" targetFramework="net45" />
<package id="System.Text.Encoding" version="4.3.0" targetFramework="net45" />
<package id="System.Text.Encoding.Extensions" version="4.3.0" targetFramework="net45" />
<package id="System.Text.RegularExpressions" version="4.3.0" targetFramework="net45" />
<package id="System.Threading" version="4.3.0" targetFramework="net45" />
<package id="System.Threading.Tasks" version="4.3.0" targetFramework="net45" />
<package id="System.Xml.ReaderWriter" version="4.3.0" targetFramework="net45" />
<package id="System.Xml.XDocument" version="4.3.0" targetFramework="net45" />
<package id="xunit" version="2.3.0-beta3-build3705" targetFramework="net45" />
<package id="xunit.abstractions" version="2.0.1" targetFramework="net45" />
<package id="xunit.analyzers" version="0.5.0" targetFramework="net45" />
<package id="xunit.assert" version="2.3.0-beta3-build3705" targetFramework="net45" />
<package id="xunit.core" version="2.3.0-beta3-build3705" targetFramework="net45" />
<package id="xunit.extensibility.core" version="2.3.0-beta3-build3705" targetFramework="net45" />
<package id="xunit.extensibility.execution" version="2.3.0-beta3-build3705" targetFramework="net45" />
<package id="xunit.runner.visualstudio" version="2.3.0-beta3-build3705" targetFramework="net45" developmentDependency="true" />
</packages>

View File

@@ -0,0 +1,43 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp1.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<Compile Include="..\EngineIoClientDotNet.Tests.mono\ClientTests\BinaryPollingTest.cs" Link="ClientTests\BinaryPollingTest.cs" />
<Compile Include="..\EngineIoClientDotNet.Tests.mono\ClientTests\BinaryWebSocketTest.cs" Link="ClientTests\BinaryWebSocketTest.cs" />
<Compile Include="..\EngineIoClientDotNet.Tests.mono\ClientTests\Connection.cs" Link="ClientTests\Connection.cs" />
<Compile Include="..\EngineIoClientDotNet.Tests.mono\ClientTests\ConnectionConstants.cs" Link="ClientTests\ConnectionConstants.cs" />
<Compile Include="..\EngineIoClientDotNet.Tests.mono\ClientTests\ConnectionTest.cs" Link="ClientTests\ConnectionTest.cs" />
<Compile Include="..\EngineIoClientDotNet.Tests.mono\ClientTests\HandshakeDataTests.cs" Link="ClientTests\HandshakeDataTests.cs" />
<Compile Include="..\EngineIoClientDotNet.Tests.mono\ClientTests\ServerConnectionTest.cs" Link="ClientTests\ServerConnectionTest.cs" />
<Compile Include="..\EngineIoClientDotNet.Tests.mono\ClientTests\SocketTest.cs" Link="ClientTests\SocketTest.cs" />
<Compile Include="..\EngineIoClientDotNet.Tests.mono\ClientTests\SSLServerConnectionTest.cs" Link="ClientTests\SSLServerConnectionTest.cs" />
<Compile Include="..\EngineIoClientDotNet.Tests.mono\ClientTests\TransportTest.cs" Link="ClientTests\TransportTest.cs" />
<Compile Include="..\EngineIoClientDotNet.Tests.mono\ClientTests\UsageTest.cs" Link="ClientTests\UsageTest.cs" />
<Compile Include="..\EngineIoClientDotNet.Tests.mono\ComponentEmitterTests\EmitterTests.cs" Link="ComponentEmitterTests\EmitterTests.cs" />
<Compile Include="..\EngineIoClientDotNet.Tests.mono\ModulesTests\ParseQSTests.cs" Link="ModulesTests\ParseQSTests.cs" />
<Compile Include="..\EngineIoClientDotNet.Tests.mono\ModulesTests\UTF8Tests.cs" Link="ModulesTests\UTF8Tests.cs" />
<Compile Include="..\EngineIoClientDotNet.Tests.mono\ParserTests\DecodeTests.cs" Link="ParserTests\DecodeTests.cs" />
<Compile Include="..\EngineIoClientDotNet.Tests.mono\ParserTests\TestsParser.cs" Link="ParserTests\TestsParser.cs" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0" />
<PackageReference Include="xunit" Version="2.2.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.2.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\EngineIoClientDotNet.netstandard1.3\EngineIoClientDotNet.netstandard1.3.csproj" />
</ItemGroup>
<ItemGroup>
<Folder Include="ModulesTests\" />
<Folder Include="ParserTests\" />
<Folder Include="ComponentEmitterTests\" />
<Folder Include="ClientTests\" />
</ItemGroup>
</Project>

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;
}
}
}

View File

@@ -0,0 +1,317 @@

using System.Collections.Immutable;
using Quobject.EngineIoClientDotNet.Modules;
using System;
namespace Quobject.EngineIoClientDotNet.ComponentEmitter
{
/// <remarks>
/// The event emitter which is ported from the JavaScript module.
/// <see href="https://github.com/component/emitter">https://github.com/component/emitter</see>
/// </remarks>
public class Emitter
{
private ImmutableDictionary<string, ImmutableList<IListener>> callbacks;
private ImmutableDictionary<IListener, IListener> _onceCallbacks;
public Emitter()
{
this.Off();
}
/// <summary>
/// Executes each of listeners with the given args.
/// </summary>
/// <param name="eventString">an event name.</param>
/// <param name="args"></param>
/// <returns>a reference to this object.</returns>
public virtual Emitter Emit(string eventString, params object[] args)
{
//var log = LogManager.GetLogger(Global.CallerName());
//log.Info("Emitter emit event = " + eventString);
if (this.callbacks.ContainsKey(eventString))
{
try
{
//handle in try/catch the emit
ImmutableList<IListener> callbacksLocal = this.callbacks[eventString];
foreach (var fn in callbacksLocal)
{
fn.Call(args);
}
}
catch { }
}
return this;
}
/// <summary>
/// Listens on the event.
/// </summary>
/// <param name="eventString">event name</param>
/// <param name="fn"></param>
/// <returns>a reference to this object</returns>
public Emitter On(string eventString, IListener fn)
{
if (!this.callbacks.ContainsKey(eventString))
{
//this.callbacks[eventString] = ImmutableList<IListener>.Empty;
this.callbacks = this.callbacks.Add(eventString, ImmutableList<IListener>.Empty);
}
ImmutableList<IListener> callbacksLocal = this.callbacks[eventString];
callbacksLocal = callbacksLocal.Add(fn);
//this.callbacks[eventString] = callbacksLocal;
this.callbacks = this.callbacks.Remove(eventString).Add(eventString, callbacksLocal);
return this;
}
/// <summary>
/// Listens on the event.
/// </summary>
/// <param name="eventString">event name</param>
/// <param name="fn"></param>
/// <returns>a reference to this object</returns>
public Emitter On(string eventString, Action fn)
{
var listener = new ListenerImpl(fn);
return this.On(eventString, listener);
}
/// <summary>
/// Listens on the event.
/// </summary>
/// <param name="eventString">event name</param>
/// <param name="fn"></param>
/// <returns>a reference to this object</returns>
public Emitter On(string eventString, Action<object> fn)
{
var listener = new ListenerImpl(fn);
return this.On(eventString, listener);
}
/// <summary>
/// Adds a one time listener for the event.
/// </summary>
/// <param name="eventString">an event name.</param>
/// <param name="fn"></param>
/// <returns>a reference to this object</returns>
public Emitter Once(string eventString, IListener fn)
{
var on = new OnceListener(eventString, fn, this);
_onceCallbacks = _onceCallbacks.Add(fn, on);
this.On(eventString, on);
return this;
}
/// <summary>
/// Adds a one time listener for the event.
/// </summary>
/// <param name="eventString">an event name.</param>
/// <param name="fn"></param>
/// <returns>a reference to this object</returns>
public Emitter Once(string eventString, Action fn)
{
var listener = new ListenerImpl(fn);
return this.Once(eventString, listener);
}
/// <summary>
/// Removes all registered listeners.
/// </summary>
/// <returns>a reference to this object.</returns>
public Emitter Off()
{
callbacks = ImmutableDictionary.Create<string, ImmutableList<IListener>>();
_onceCallbacks = ImmutableDictionary.Create<IListener, IListener>();
return this;
}
/// <summary>
/// Removes all listeners of the specified event.
/// </summary>
/// <param name="eventString">an event name</param>
/// <returns>a reference to this object.</returns>
public Emitter Off(string eventString)
{
try
{
ImmutableList<IListener> retrievedValue;
if (!callbacks.TryGetValue(eventString, out retrievedValue))
{
var log = LogManager.GetLogger(Global.CallerName());
log.Info(string.Format("Emitter.Off Could not remove {0}", eventString));
}
if (retrievedValue != null)
{
callbacks = callbacks.Remove(eventString);
foreach (var listener in retrievedValue)
{
_onceCallbacks.Remove(listener);
}
}
}
catch (Exception)
{
this.Off();
}
return this;
}
/// <summary>
/// Removes the listener
/// </summary>
/// <param name="eventString">an event name</param>
/// <param name="fn"></param>
/// <returns>a reference to this object.</returns>
public Emitter Off(string eventString, IListener fn)
{
try
{
if (this.callbacks.ContainsKey(eventString))
{
ImmutableList<IListener> callbacksLocal = this.callbacks[eventString];
IListener offListener;
_onceCallbacks.TryGetValue(fn, out offListener);
_onceCallbacks = _onceCallbacks.Remove(fn);
if (callbacksLocal.Count > 0 && callbacksLocal.Contains(offListener ?? fn))
{
callbacksLocal = callbacksLocal.Remove(offListener ?? fn);
this.callbacks = this.callbacks.Remove(eventString);
this.callbacks = this.callbacks.Add(eventString, callbacksLocal);
}
}
}catch(Exception)
{
this.Off();
}
return this;
}
/// <summary>
/// Returns a list of listeners for the specified event.
/// </summary>
/// <param name="eventString">an event name.</param>
/// <returns>a reference to this object</returns>
public ImmutableList<IListener> Listeners(string eventString)
{
if (this.callbacks.ContainsKey(eventString))
{
ImmutableList<IListener> callbacksLocal = this.callbacks[eventString];
return callbacksLocal ?? ImmutableList<IListener>.Empty;
}
return ImmutableList<IListener>.Empty;
}
/// <summary>
/// Check if this emitter has listeners for the specified event.
/// </summary>
/// <param name="eventString">an event name</param>
/// <returns>bool</returns>
public bool HasListeners(string eventString)
{
return this.Listeners(eventString).Count > 0;
}
}
public interface IListener: System.IComparable<IListener>
{
int GetId();
void Call(params object[] args);
}
public class ListenerImpl : IListener
{
private static int id_counter = 0;
private int Id;
private readonly Action fn1;
private readonly Action<object> fn;
public ListenerImpl(Action<object> fn)
{
this.fn = fn;
this.Id = id_counter++;
}
public ListenerImpl(Action fn)
{
this.fn1 = fn;
this.Id = id_counter++;
}
public void Call(params object[] args)
{
if (fn != null)
{
var arg = args.Length > 0 ? args[0] : null;
fn(arg);
}
else
{
fn1();
}
}
public int CompareTo(IListener other)
{
return this.GetId().CompareTo(other.GetId());
}
public int GetId()
{
return Id;
}
}
public class OnceListener : IListener
{
private static int id_counter = 0;
private int Id;
private readonly string _eventString;
private readonly IListener _fn;
private readonly Emitter _emitter;
public OnceListener(string eventString, IListener fn, Emitter emitter)
{
this._eventString = eventString;
this._fn = fn;
this._emitter = emitter;
Id = id_counter++;
}
void IListener.Call(params object[] args)
{
_emitter.Off(_eventString, this);
_fn.Call(args);
}
public int CompareTo(IListener other)
{
return this.GetId().CompareTo(other.GetId());
}
public int GetId()
{
return Id;
}
}
}

View File

@@ -0,0 +1,322 @@

using System.Collections.Concurrent;
using System.Collections.Generic;
using Quobject.EngineIoClientDotNet.Modules;
using System;
namespace Quobject.EngineIoClientDotNet.ComponentEmitter
{
/// <remarks>
/// The event emitter which is ported from the JavaScript module.
/// <see href="https://github.com/component/emitter">https://github.com/component/emitter</see>
/// </remarks>
public class Emitter
{
private ConcurrentDictionary<string, List<IListener>> callbacks;
private ConcurrentDictionary<IListener, IListener> _onceCallbacks;
public Emitter()
{
this.Off();
}
/// <summary>
/// Executes each of listeners with the given args.
/// </summary>
/// <param name="eventString">an event name.</param>
/// <param name="args"></param>
/// <returns>a reference to this object.</returns>
public virtual Emitter Emit(string eventString, params object[] args)
{
//var log = LogManager.GetLogger(Global.CallerName());
//log.Info("Emitter emit event = " + eventString);
if (this.callbacks.ContainsKey(eventString))
{
List<IListener> callbacksLocal = this.callbacks[eventString];
var listCopy = new List<IListener>();
listCopy.AddRange(callbacksLocal);
foreach (var fn in listCopy)
{
fn.Call(args);
}
}
return this;
}
/// <summary>
/// Listens on the event.
/// </summary>
/// <param name="eventString">event name</param>
/// <param name="fn"></param>
/// <returns>a reference to this object</returns>
public Emitter On(string eventString, IListener fn)
{
if (!this.callbacks.ContainsKey(eventString))
{
//this.callbacks[eventString] = List<IListener>();
this.callbacks.TryAdd(eventString,new List<IListener>());
}
List<IListener> callbacksLocal = this.callbacks[eventString];
callbacksLocal.Add(fn);
//this.callbacks[eventString] = callbacksLocal;
List<IListener> outref;
this.callbacks.TryRemove(eventString, out outref);
this.callbacks.TryAdd(eventString, callbacksLocal);
return this;
}
/// <summary>
/// Listens on the event.
/// </summary>
/// <param name="eventString">event name</param>
/// <param name="fn"></param>
/// <returns>a reference to this object</returns>
public Emitter On(string eventString, Action fn)
{
var listener = new ListenerImpl(fn);
return this.On(eventString, listener);
}
/// <summary>
/// Listens on the event.
/// </summary>
/// <param name="eventString">event name</param>
/// <param name="fn"></param>
/// <returns>a reference to this object</returns>
public Emitter On(string eventString, Action<object> fn)
{
var listener = new ListenerImpl(fn);
return this.On(eventString, listener);
}
/// <summary>
/// Adds a one time listener for the event.
/// </summary>
/// <param name="eventString">an event name.</param>
/// <param name="fn"></param>
/// <returns>a reference to this object</returns>
public Emitter Once(string eventString, IListener fn)
{
var on = new OnceListener(eventString, fn, this);
_onceCallbacks.TryAdd(fn, on);
this.On(eventString, on);
return this;
}
/// <summary>
/// Adds a one time listener for the event.
/// </summary>
/// <param name="eventString">an event name.</param>
/// <param name="fn"></param>
/// <returns>a reference to this object</returns>
public Emitter Once(string eventString, Action fn)
{
var listener = new ListenerImpl(fn);
return this.Once(eventString, listener);
}
/// <summary>
/// Removes all registered listeners.
/// </summary>
/// <returns>a reference to this object.</returns>
public Emitter Off()
{
callbacks = new ConcurrentDictionary<string, List<IListener>>();
_onceCallbacks = new ConcurrentDictionary<IListener, IListener>();
return this;
}
/// <summary>
/// Removes all listeners of the specified event.
/// </summary>
/// <param name="eventString">an event name</param>
/// <returns>a reference to this object.</returns>
public Emitter Off(string eventString)
{
try
{
List<IListener> retrievedValue;
if (!callbacks.TryGetValue(eventString, out retrievedValue))
{
var log = LogManager.GetLogger(Global.CallerName());
log.Info(string.Format("Emitter.Off Could not remove {0}", eventString));
}
if (retrievedValue != null)
{
List<IListener> outref;
IListener ilistenerOutRef;
callbacks.TryRemove(eventString, out outref);
foreach (var listener in retrievedValue)
{
_onceCallbacks.TryRemove(listener, out ilistenerOutRef);
}
}
}
catch (Exception)
{
this.Off();
}
return this;
}
/// <summary>
/// Removes the listener
/// </summary>
/// <param name="eventString">an event name</param>
/// <param name="fn"></param>
/// <returns>a reference to this object.</returns>
public Emitter Off(string eventString, IListener fn)
{
try
{
if (this.callbacks.ContainsKey(eventString))
{
List<IListener> callbacksLocal = this.callbacks[eventString];
IListener offListener;
//_onceCallbacks.TryGetValue(fn,out offListener);
_onceCallbacks.TryRemove(fn, out offListener);
if (callbacksLocal.Count > 0 && callbacksLocal.Contains(offListener ?? fn))
{
callbacksLocal.Remove(offListener ?? fn);
List<IListener> outref;
this.callbacks.TryRemove(eventString, out outref);
this.callbacks.TryAdd(eventString, callbacksLocal);
}
}
}
catch (Exception)
{
this.Off();
}
return this;
}
/// <summary>
/// Returns a list of listeners for the specified event.
/// </summary>
/// <param name="eventString">an event name.</param>
/// <returns>a reference to this object</returns>
public List<IListener> Listeners(string eventString)
{
if (this.callbacks.ContainsKey(eventString))
{
List<IListener> callbacksLocal = this.callbacks[eventString];
return callbacksLocal ?? new List<IListener>();
}
return new List<IListener>();
}
/// <summary>
/// Check if this emitter has listeners for the specified event.
/// </summary>
/// <param name="eventString">an event name</param>
/// <returns>bool</returns>
public bool HasListeners(string eventString)
{
return this.Listeners(eventString).Count > 0;
}
}
public interface IListener: System.IComparable<IListener>
{
int GetId();
void Call(params object[] args);
}
public class ListenerImpl : IListener
{
private static int id_counter = 0;
private int Id;
private readonly Action fn1;
private readonly Action<object> fn;
public ListenerImpl(Action<object> fn)
{
this.fn = fn;
this.Id = id_counter++;
}
public ListenerImpl(Action fn)
{
this.fn1 = fn;
this.Id = id_counter++;
}
public void Call(params object[] args)
{
if (fn != null)
{
var arg = args.Length > 0 ? args[0] : null;
fn(arg);
}
else
{
fn1();
}
}
public int CompareTo(IListener other)
{
return this.GetId().CompareTo(other.GetId());
}
public int GetId()
{
return Id;
}
}
public class OnceListener : IListener
{
private static int id_counter = 0;
private int Id;
private readonly string _eventString;
private readonly IListener _fn;
private readonly Emitter _emitter;
public OnceListener(string eventString, IListener fn, Emitter emitter)
{
this._eventString = eventString;
this._fn = fn;
this._emitter = emitter;
Id = id_counter++;
}
void IListener.Call(params object[] args)
{
_emitter.Off(_eventString, this);
_fn.Call(args);
}
public int CompareTo(IListener other)
{
return this.GetId().CompareTo(other.GetId());
}
public int GetId()
{
return Id;
}
}
}

View File

@@ -0,0 +1,113 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{B6731266-B247-4A63-B10B-F938288248B6}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>EngineIoClientDotNet</RootNamespace>
<AssemblyName>EngineIoClientDotNet</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>packages\Newtonsoft.Json.10.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="SuperSocket.ClientEngine, Version=0.8.0.8, Culture=neutral, processorArchitecture=MSIL">
<HintPath>packages\SuperSocket.ClientEngine.Core.0.8.0.8\lib\net45\SuperSocket.ClientEngine.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="WebSocket4Net, Version=0.15.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>packages\WebSocket4Net.0.15.0-beta6\lib\net45\WebSocket4Net.dll</HintPath>
<Private>True</Private>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="..\Quobject.Collections.Immutable\AvlNode.cs">
<Link>Quobject.Collections.Immutable\AvlNode.cs</Link>
</Compile>
<Compile Include="..\Quobject.Collections.Immutable\IImmutableDictionary.cs">
<Link>Quobject.Collections.Immutable\IImmutableDictionary.cs</Link>
</Compile>
<Compile Include="..\Quobject.Collections.Immutable\IImmutableList.cs">
<Link>Quobject.Collections.Immutable\IImmutableList.cs</Link>
</Compile>
<Compile Include="..\Quobject.Collections.Immutable\IImmutableQueue.cs">
<Link>Quobject.Collections.Immutable\IImmutableQueue.cs</Link>
</Compile>
<Compile Include="..\Quobject.Collections.Immutable\IImmutableSet.cs">
<Link>Quobject.Collections.Immutable\IImmutableSet.cs</Link>
</Compile>
<Compile Include="..\Quobject.Collections.Immutable\IImmutableStack.cs">
<Link>Quobject.Collections.Immutable\IImmutableStack.cs</Link>
</Compile>
<Compile Include="..\Quobject.Collections.Immutable\ImmutableDictionary.cs">
<Link>Quobject.Collections.Immutable\ImmutableDictionary.cs</Link>
</Compile>
<Compile Include="..\Quobject.Collections.Immutable\ImmutableList.cs">
<Link>Quobject.Collections.Immutable\ImmutableList.cs</Link>
</Compile>
<Compile Include="..\Quobject.Collections.Immutable\ImmutableQueue.cs">
<Link>Quobject.Collections.Immutable\ImmutableQueue.cs</Link>
</Compile>
<Compile Include="..\Quobject.Collections.Immutable\ImmutableStack.cs">
<Link>Quobject.Collections.Immutable\ImmutableStack.cs</Link>
</Compile>
<Compile Include="Client\EngineIOException.cs" />
<Compile Include="Client\HandshakeData.cs" />
<Compile Include="Client\Socket.cs" />
<Compile Include="Client\Transport.cs" />
<Compile Include="Client\Transports\Polling.cs" />
<Compile Include="Client\Transports\PollingXHR.cs" />
<Compile Include="Client\Transports\WebSocket.cs" />
<Compile Include="ComponentEmitter\Emitter.cs" />
<Compile Include="Modules\Global.cs" />
<Compile Include="Modules\LogManager.cs" />
<Compile Include="Modules\ParseQS.cs" />
<Compile Include="Modules\ServerCertificate.cs" />
<Compile Include="Modules\UTF8.cs" />
<Compile Include="Modules\UTF8Exception.cs" />
<Compile Include="Parser\Buffer.cs" />
<Compile Include="Parser\ByteBuffer.cs" />
<Compile Include="Parser\IDecodePayloadCallback.cs" />
<Compile Include="Parser\IEncodeCallback.cs" />
<Compile Include="Parser\Packet.cs" />
<Compile Include="Parser\Parser.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Thread\EasyTimer.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@@ -0,0 +1,32 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2012
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EngineIoClientDotNet.mono", "EngineIoClientDotNet.mono.csproj", "{B6731266-B247-4A63-B10B-F938288248B6}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EngineIoClientDotNet.Tests.mono", "..\EngineIoClientDotNet.Tests.mono\EngineIoClientDotNet.Tests.mono.csproj", "{382C2A10-8043-49C6-9DE5-39CA25C2418C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Quobject.Collections.Immutable", "..\Quobject.Collections.Immutable\Quobject.Collections.Immutable.csproj", "{024A2111-4B19-44D7-917E-8514CF632469}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{B6731266-B247-4A63-B10B-F938288248B6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B6731266-B247-4A63-B10B-F938288248B6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B6731266-B247-4A63-B10B-F938288248B6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B6731266-B247-4A63-B10B-F938288248B6}.Release|Any CPU.Build.0 = Release|Any CPU
{382C2A10-8043-49C6-9DE5-39CA25C2418C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{382C2A10-8043-49C6-9DE5-39CA25C2418C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{382C2A10-8043-49C6-9DE5-39CA25C2418C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{382C2A10-8043-49C6-9DE5-39CA25C2418C}.Release|Any CPU.Build.0 = Release|Any CPU
{024A2111-4B19-44D7-917E-8514CF632469}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{024A2111-4B19-44D7-917E-8514CF632469}.Debug|Any CPU.Build.0 = Debug|Any CPU
{024A2111-4B19-44D7-917E-8514CF632469}.Release|Any CPU.ActiveCfg = Release|Any CPU
{024A2111-4B19-44D7-917E-8514CF632469}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@@ -0,0 +1,48 @@
using System;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text.RegularExpressions;
namespace Quobject.EngineIoClientDotNet.Modules
{
public static class Global
{
public static string EncodeURIComponent(string str)
{
//http://stackoverflow.com/a/4550600/1109316
return Uri.EscapeDataString(str);
}
public static string DecodeURIComponent(string str)
{
return Uri.UnescapeDataString(str);
}
public static string CallerName([CallerMemberName]string caller = "", [CallerLineNumber]int number = 0, [CallerFilePath]string path = "")
{
var s = path.Split('\\');
var fileName = s.LastOrDefault();
if (path.Contains("SocketIoClientDotNet.Tests"))
{
path = "SocketIoClientDotNet.Tests";
}
else if (path.Contains("SocketIoClientDotNet"))
{
path = "SocketIoClientDotNet";
}
else if (path.Contains("EngineIoClientDotNet"))
{
path = "EngineIoClientDotNet";
}
return string.Format("{0}-{1}:{2}#{3}",path, fileName, caller, number);
}
//from http://stackoverflow.com/questions/8767103/how-to-remove-invalid-code-points-from-a-string
public static string StripInvalidUnicodeCharacters(string str)
{
var invalidCharactersRegex = new Regex("([\ud800-\udbff](?![\udc00-\udfff]))|((?<![\ud800-\udbff])[\udc00-\udfff])");
return invalidCharactersRegex.Replace(str, "");
}
}
}

View File

@@ -0,0 +1,49 @@
using System;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text.RegularExpressions;
using System.Web;
namespace Quobject.EngineIoClientDotNet.Modules
{
public static class Global
{
public static string EncodeURIComponent(string str)
{
//http://stackoverflow.com/a/4550600/1109316
return Uri.EscapeDataString(str);
}
public static string DecodeURIComponent(string str)
{
return Uri.UnescapeDataString(str);
}
public static string CallerName(string caller = "", int number = 0, string path = "")
{
var s = path.Split('\\');
var fileName = s.LastOrDefault();
if (path.Contains("SocketIoClientDotNet.Tests"))
{
path = "SocketIoClientDotNet.Tests";
}
else if (path.Contains("SocketIoClientDotNet"))
{
path = "SocketIoClientDotNet";
}
else if (path.Contains("EngineIoClientDotNet"))
{
path = "EngineIoClientDotNet";
}
return string.Format("{0}-{1}:{2}#{3}",path, fileName, caller, number);
}
//from http://stackoverflow.com/questions/8767103/how-to-remove-invalid-code-points-from-a-string
public static string StripInvalidUnicodeCharacters(string str)
{
var invalidCharactersRegex = new Regex("([\ud800-\udbff](?![\udc00-\udfff]))|((?<![\ud800-\udbff])[\udc00-\udfff])");
return invalidCharactersRegex.Replace(str, "");
}
}
}

View File

@@ -0,0 +1,177 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Runtime.CompilerServices;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
namespace Quobject.EngineIoClientDotNet.Modules
{
public static class Global
{
public static string EncodeURIComponent(string str)
{
//http://stackoverflow.com/a/4550600/1109316
return Uri.EscapeDataString(str);
}
public static string DecodeURIComponent(string str)
{
return Uri.UnescapeDataString(str);
}
public static string CallerName([CallerMemberName]string caller = "", [CallerLineNumber]int number = 0, [CallerFilePath]string path = "")
{
var s = path.Split('\\');
var fileName = s.LastOrDefault();
if (path.Contains("SocketIoClientDotNet.Tests"))
{
path = "SocketIoClientDotNet.Tests";
}
else if (path.Contains("SocketIoClientDotNet"))
{
path = "SocketIoClientDotNet";
}
else if (path.Contains("EngineIoClientDotNet"))
{
path = "EngineIoClientDotNet";
}
return string.Format("{0}-{1}:{2}#{3}", path, fileName, caller, number);
}
//from http://stackoverflow.com/questions/8767103/how-to-remove-invalid-code-points-from-a-string
public static string StripInvalidUnicodeCharacters(string str)
{
var invalidCharactersRegex = new Regex("([\ud800-\udbff](?![\udc00-\udfff]))|((?<![\ud800-\udbff])[\udc00-\udfff])");
return invalidCharactersRegex.Replace(str, "");
}
}
// from http://social.msdn.microsoft.com/Forums/en-US/163ef755-ff7b-4ea5-b226-bbe8ef5f4796/is-there-a-pattern-for-calling-an-async-method-synchronously?forum=async
public static class AsyncInline
{
public static void Run(Func<Task> item)
{
var oldContext = SynchronizationContext.Current;
var synch = new ExclusiveSynchronizationContext();
SynchronizationContext.SetSynchronizationContext(synch);
synch.Post(async _ =>
{
try
{
await item();
}
catch (Exception e)
{
synch.InnerException = e;
throw;
}
finally
{
synch.EndMessageLoop();
}
}, null);
synch.BeginMessageLoop();
SynchronizationContext.SetSynchronizationContext(oldContext);
}
public static T Run<T>(Func<Task<T>> item)
{
var oldContext = SynchronizationContext.Current;
var synch = new ExclusiveSynchronizationContext();
SynchronizationContext.SetSynchronizationContext(synch);
T ret = default(T);
synch.Post(async _ =>
{
try
{
ret = await
item();
}
catch (Exception e)
{
synch.InnerException = e;
throw;
}
finally
{
synch.EndMessageLoop();
}
}, null);
synch.BeginMessageLoop();
SynchronizationContext.SetSynchronizationContext(oldContext);
return ret;
}
private class ExclusiveSynchronizationContext : SynchronizationContext
{
private bool done;
public Exception InnerException { get; set; }
readonly AutoResetEvent workItemsWaiting = new AutoResetEvent(false);
readonly Queue<Tuple<SendOrPostCallback, object>> items =
new Queue<Tuple<SendOrPostCallback, object>>();
public override void Send(SendOrPostCallback d, object state)
{
throw new NotSupportedException("We cannot send to our same thread");
}
public override void Post(SendOrPostCallback d, object state)
{
lock (items)
{
items.Enqueue(Tuple.Create(d, state));
}
workItemsWaiting.Set();
}
public void EndMessageLoop()
{
Post(_ => done = true, null);
}
public void BeginMessageLoop()
{
while (!done)
{
Tuple<SendOrPostCallback, object> task = null;
lock (items)
{
if (items.Count > 0)
{
task = items.Dequeue();
}
}
if (task != null)
{
task.Item1(task.Item2);
if (InnerException != null) // the method threw an exeption
{
throw new AggregateException("AsyncInline.Run method threw an exception.",
InnerException);
}
}
else
{
workItemsWaiting.WaitOne();
}
}
}
public override SynchronizationContext CreateCopy()
{
return this;
}
}
}
}

View File

@@ -0,0 +1,51 @@
using System;
using System.Linq;
using System.Net;
using System.Runtime.CompilerServices;
using System.Text.RegularExpressions;
namespace Quobject.EngineIoClientDotNet.Modules
{
public static class Global
{
public static string EncodeURIComponent(string str)
{
//http://stackoverflow.com/a/4550600/1109316
return Uri.EscapeDataString(str);
}
public static string DecodeURIComponent(string str)
{
return Uri.UnescapeDataString(str);
}
public static string CallerName([CallerMemberName]string caller = "", [CallerLineNumber]int number = 0, [CallerFilePath]string path = "")
{
var s = path.Split('\\');
var fileName = s.LastOrDefault();
if (path.Contains("SocketIoClientDotNet.Tests"))
{
path = "SocketIoClientDotNet.Tests";
}
else if (path.Contains("SocketIoClientDotNet"))
{
path = "SocketIoClientDotNet";
}
else if (path.Contains("EngineIoClientDotNet"))
{
path = "EngineIoClientDotNet";
}
return string.Format("{0}-{1}:{2}#{3}", path, fileName, caller, number);
}
//from http://stackoverflow.com/questions/8767103/how-to-remove-invalid-code-points-from-a-string
public static string StripInvalidUnicodeCharacters(string str)
{
var invalidCharactersRegex = new Regex("([\ud800-\udbff](?![\udc00-\udfff]))|((?<![\ud800-\udbff])[\udc00-\udfff])");
return invalidCharactersRegex.Replace(str, "");
}
}
}

View File

@@ -0,0 +1,109 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Text;
namespace Quobject.EngineIoClientDotNet.Modules
{
public class LogManager
{
private const string LogFilePath = "XunitTrace.log";
private static readonly LogManager EmptyLogger = new LogManager(null);
private static StreamWriter writer;
private readonly string type;
#region Statics
public static void SetupLogManager()
{}
public static LogManager GetLogger(string type)
{
return new LogManager(type);
}
public static LogManager GetLogger(Type type)
{
return GetLogger(type.ToString());
}
public static LogManager GetLogger(MethodBase methodBase)
{
#if DEBUG
string declaringType = methodBase.DeclaringType != null
? methodBase.DeclaringType.ToString()
: string.Empty;
string fullType = string.Format("{0}#{1}", declaringType, methodBase.Name);
return GetLogger(fullType);
#else
return EmptyLogger;
#endif
}
#endregion
public LogManager(string type)
{
this.type = type;
}
public static bool Enabled { get; set; }
private static StreamWriter Writer
{
get
{
if (writer == null)
{
FileStream fs = new FileStream(
LogFilePath, FileMode.Append, FileAccess.Write, FileShare.Read);
writer = new StreamWriter(fs, Encoding.UTF8)
{
AutoFlush = true
};
}
return writer;
}
}
[Conditional("DEBUG")]
public void Info(string msg)
{
if (!Enabled)
{
return;
}
Writer.WriteLine(
"{0:yyyy-MM-dd HH:mm:ss fff} [] {1} {2}",
DateTime.Now,
this.type,
Global.StripInvalidUnicodeCharacters(msg));
}
[Conditional("DEBUG")]
public void Error(string p, Exception exception)
{
//this.Info($"ERROR {p} {exception.Message} {exception.StackTrace}");
this.Info(String.Format("ERROR {0} {1} {2}", p, exception.Message, exception.StackTrace));
if (exception.InnerException != null)
{
//this.Info($"ERROR exception.InnerException {p} {exception.InnerException.Message} {exception.InnerException.StackTrace}");
this.Info(String.Format("ERROR {0} {1} {2} {3}", exception.InnerException, p,
exception.InnerException.Message, exception.InnerException.StackTrace));
}
}
[Conditional("DEBUG")]
internal void Error(Exception e)
{
this.Error("", e);
}
}
}

View File

@@ -0,0 +1,79 @@
using System.Collections.Immutable;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Quobject.EngineIoClientDotNet.Modules
{
/// <remarks>
/// Provides methods for parsing a query string into an object, and vice versa.
/// Ported from the JavaScript module.
/// <see href="https://www.npmjs.org/package/parseqs">https://www.npmjs.org/package/parseqs</see>
/// </remarks>
public class ParseQS
{
/// <summary>
/// Compiles a querystring
/// Returns string representation of the object
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public static string Encode(ImmutableDictionary<string, string> obj)
{
var sb = new StringBuilder();
foreach (var key in obj.Keys.OrderBy(x=>x))
{
if (sb.Length > 0)
{
sb.Append("&");
}
sb.Append(Global.EncodeURIComponent(key));
sb.Append("=");
sb.Append(Global.EncodeURIComponent(obj[key]));
}
return sb.ToString();
}
/// <summary>
/// Compiles a querystring
/// Returns string representation of the object
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
internal static string Encode(System.Collections.Generic.Dictionary<string, string> obj)
{
var sb = new StringBuilder();
foreach (var key in obj.Keys)
{
if (sb.Length > 0)
{
sb.Append("&");
}
sb.Append(Global.EncodeURIComponent(key));
sb.Append("=");
sb.Append(Global.EncodeURIComponent(obj[key]));
}
return sb.ToString();
}
/// <summary>
/// Parses a simple querystring into an object
/// </summary>
/// <param name="qs"></param>
/// <returns></returns>
public static Dictionary<string, string> Decode(string qs)
{
var qry = new Dictionary<string, string>();
var pairs = qs.Split('&');
for (int i = 0; i < pairs.Length; i++)
{
var pair = pairs[i].Split('=');
qry.Add(Global.DecodeURIComponent(pair[0]), Global.DecodeURIComponent(pair[1]));
}
return qry;
}
}
}

View File

@@ -0,0 +1,82 @@

using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Quobject.EngineIoClientDotNet.Modules
{
/// <remarks>
/// Provides methods for parsing a query string into an object, and vice versa.
/// Ported from the JavaScript module.
/// <see href="https://www.npmjs.org/package/parseqs">https://www.npmjs.org/package/parseqs</see>
/// </remarks>
public class ParseQS
{
/// <summary>
/// Compiles a querystring
/// Returns string representation of the object
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public static string Encode(ConcurrentDictionary<string, string> obj)
{
var sb = new StringBuilder();
foreach (var key in obj.Keys.OrderBy(x=>x))
{
if (sb.Length > 0)
{
sb.Append("&");
}
sb.Append(Global.EncodeURIComponent(key));
sb.Append("=");
sb.Append(Global.EncodeURIComponent(obj[key]));
}
return sb.ToString();
}
/// <summary>
/// Compiles a querystring
/// Returns string representation of the object
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
internal static string Encode(System.Collections.Generic.Dictionary<string, string> obj)
{
var sb = new StringBuilder();
foreach (var key in obj.Keys)
{
if (sb.Length > 0)
{
sb.Append("&");
}
sb.Append(Global.EncodeURIComponent(key));
sb.Append("=");
sb.Append(Global.EncodeURIComponent(obj[key]));
}
return sb.ToString();
}
/// <summary>
/// Parses a simple querystring into an object
/// </summary>
/// <param name="qs"></param>
/// <returns></returns>
public static Dictionary<string, string> Decode(string qs)
{
var qry = new Dictionary<string, string>();
var pairs = qs.Split('&');
for (int i = 0; i < pairs.Length; i++)
{
var pair = pairs[i].Split('=');
qry.Add(Global.DecodeURIComponent(pair[0]), Global.DecodeURIComponent(pair[1]));
}
return qry;
}
}
}

View File

@@ -0,0 +1,20 @@
using System.Net;
namespace Quobject.EngineIoClientDotNet.Modules
{
public class ServerCertificate
{
public static bool Ignore { get; set; }
static ServerCertificate()
{
Ignore = false;
}
public static void IgnoreServerCertificateValidation()
{
ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) => true;
Ignore = true;
}
}
}

View File

@@ -0,0 +1,19 @@

namespace Quobject.EngineIoClientDotNet.Modules
{
public class ServerCertificate
{
public static bool Ignore { get; set; }
static ServerCertificate()
{
Ignore = false;
}
public static void IgnoreServerCertificateValidation()
{
//ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) => true;
Ignore = true;
}
}
}

View File

@@ -0,0 +1,17 @@
namespace Quobject.EngineIoClientDotNet.Modules
{
public class ServerCertificate
{
public static bool Ignore { get; set; }
static ServerCertificate()
{
Ignore = false;
}
public static void IgnoreServerCertificateValidation()
{
Ignore = true;
}
}
}

View File

@@ -0,0 +1,19 @@

namespace Quobject.EngineIoClientDotNet.Modules
{
public class ServerCertificate
{
public static bool Ignore { get; set; }
static ServerCertificate()
{
Ignore = false;
}
public static void IgnoreServerCertificateValidation()
{
//ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) => true;
Ignore = true;
}
}
}

View File

@@ -0,0 +1,228 @@
using System.Collections.Generic;
using System.Text;
namespace Quobject.EngineIoClientDotNet.Modules
{
/// <remarks>
/// UTF-8 encoder/decoder ported from utf8.js.
/// Ported from the JavaScript module.
/// <see href="https://github.com/mathiasbynens/utf8.js">https://github.com/mathiasbynens/utf8.js</see>
/// </remarks>
public class UTF8
{
private static List<int> byteArray;
private static int byteCount;
private static int byteIndex;
public static string Encode(string str)
{
List<int> codePoints = Ucs2Decode(str);
var length = codePoints.Count;
var index = -1;
var byteString = new StringBuilder();
while (++index < length)
{
var codePoint = codePoints[index];
byteString.Append(EncodeCodePoint(codePoint));
}
return byteString.ToString();
}
public static string Decode(string byteString)
{
byteArray = Ucs2Decode(byteString);
byteCount = byteArray.Count;
byteIndex = 0;
var codePoints = new List<int>();
int tmp;
while ((tmp = DecodeSymbol()) != -1)
{
codePoints.Add(tmp);
}
return Ucs2Encode(codePoints);
}
private static int DecodeSymbol()
{
int byte1;
int byte2;
int byte3;
int byte4;
int codePoint;
if (byteIndex > byteCount)
{
throw new UTF8Exception("Invalid byte index");
}
if (byteIndex == byteCount)
{
return -1;
}
byte1 = byteArray[byteIndex] & 0xFF;
byteIndex++;
if ((byte1 & 0x80) == 0)
{
return byte1;
}
if ((byte1 & 0xE0) == 0xC0)
{
byte2 = ReadContinuationByte();
codePoint = ((byte1 & 0x1F) << 6) | byte2;
if (codePoint >= 0x80)
{
return codePoint;
}
else
{
throw new UTF8Exception("Invalid continuation byte");
}
}
if ((byte1 & 0xF0) == 0xE0)
{
byte2 = ReadContinuationByte();
byte3 = ReadContinuationByte();
codePoint = ((byte1 & 0x0F) << 12) | (byte2 << 6) | byte3;
if (codePoint >= 0x0800)
{
return codePoint;
}
else
{
throw new UTF8Exception("Invalid continuation byte");
}
}
if ((byte1 & 0xF8) == 0xF0)
{
byte2 = ReadContinuationByte();
byte3 = ReadContinuationByte();
byte4 = ReadContinuationByte();
codePoint = ((byte1 & 0x0F) << 0x12) | (byte2 << 0x0C) | (byte3 << 0x06) | byte4;
if (codePoint >= 0x010000 && codePoint <= 0x10FFFF)
{
return codePoint;
}
}
throw new UTF8Exception("Invalid continuation byte");
}
private static int ReadContinuationByte()
{
if (byteIndex >= byteCount)
{
throw new UTF8Exception("Invalid byte index");
}
int continuationByte = byteArray[byteIndex] & 0xFF;
byteIndex++;
if ((continuationByte & 0xC0) == 0x80)
{
return continuationByte & 0x3F;
}
throw new UTF8Exception("Invalid continuation byte");
}
private static string EncodeCodePoint(int codePoint)
{
var sb = new StringBuilder();
if ((codePoint & 0xFFFFFF80) == 0)
{
// 1-byte sequence
sb.Append((char) codePoint);
return sb.ToString();
}
if ((codePoint & 0xFFFFF800) == 0)
{
// 2-byte sequence
sb.Append((char) (((codePoint >> 6) & 0x1F) | 0xC0));
}
else if ((codePoint & 0xFFFF0000) == 0)
{
// 3-byte sequence
sb.Append((char) (((codePoint >> 12) & 0x0F) | 0xE0));
sb.Append( CreateByte(codePoint, 6));
}
else if ((codePoint & 0xFFE00000) == 0)
{
// 4-byte sequence
sb.Append((char) (((codePoint >> 18) & 0x07) | 0xF0));
sb.Append( CreateByte(codePoint, 12));
sb.Append( CreateByte(codePoint, 6));
}
sb.Append((char) ((codePoint & 0x3F) | 0x80));
return sb.ToString();
}
private static char CreateByte(int codePoint, int shift)
{
return (char)(((codePoint >> shift) & 0x3F) | 0x80);
}
private static List<int> Ucs2Decode(string str)
{
var output = new List<int>();
var counter = 0;
var length = str.Length;
while (counter < length)
{
var value = (int)str[counter++];
if (value >= 0xD800 && value <= 0xDBFF && counter < length)
{
// high surrogate, and there is a next character
var extra = (int)str[counter++];
if ((extra & 0xFC00) == 0xDC00)
{
// low surrogate
output.Add(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000);
}
else
{
// unmatched surrogate; only append this code unit, in case the next
// code unit is the high surrogate of a surrogate pair
output.Add(value);
counter--;
}
}
else
{
output.Add(value);
}
}
return output;
}
private static string Ucs2Encode(List<int> array)
{
var sb = new StringBuilder();
var index = -1;
while (++index < array.Count)
{
var value = array[index];
if (value > 0xFFFF)
{
value -= 0x10000;
sb.Append((char)(((int)((uint)value >> 10)) & 0x3FF | 0xD800));
value = 0xDC00 | value & 0x3FF;
}
sb.Append((char)value);
}
return sb.ToString();
}
}
}

View File

@@ -0,0 +1,10 @@
using System;
namespace Quobject.EngineIoClientDotNet.Modules
{
public class UTF8Exception : Exception
{
public UTF8Exception(string message) : base(message)
{}
}
}

View File

@@ -0,0 +1,41 @@
namespace Quobject.EngineIoClientDotNet.Parser
{
internal class Buffer
{
private Buffer()
{
}
public static byte[] Concat(byte[][] list)
{
int length = 0;
foreach (var buf in list)
{
length += buf.Length;
}
return Concat(list, length);
}
public static byte[] Concat(byte[][] list, int length)
{
if (list.Length == 0)
{
return new byte[0];
}
if (list.Length == 1)
{
return list[0];
}
ByteBuffer buffer = ByteBuffer.Allocate(length);
foreach (var buf in list)
{
buffer.Put(buf);
}
return buffer.Array();
}
}
}

View File

@@ -0,0 +1,162 @@
using System;
using System.IO;
namespace Quobject.EngineIoClientDotNet.Parser
{
public class ByteBuffer
{
private readonly MemoryStream _memoryStream;
private long _limit = 0;
public ByteBuffer(int length)
{
this._memoryStream = new MemoryStream();
_memoryStream.SetLength(length);
_memoryStream.Capacity = length;
_limit = length;
}
public static ByteBuffer Allocate(int length)
{
return new ByteBuffer(length);
}
internal void Put(byte[] buf)
{
_memoryStream.Write(buf,0,buf.Length);
}
internal byte[] Array()
{
return _memoryStream.ToArray();
}
internal static ByteBuffer Wrap(byte[] data)
{
var result = new ByteBuffer(data.Length);
result.Put(data);
return result;
}
/// <summary>
/// A buffer's capacity is the number of elements it contains. The capacity of a
/// buffer is never negative and never changes.
/// </summary>
public int Capacity
{
get { return _memoryStream.Capacity; }
}
/// <summary>
/// Absolute get method. Reads the byte at the given index.
/// </summary>
/// <param name="index">The index from which the byte will be read</param>
/// <returns>The byte at the given index</returns>
internal byte Get(long index)
{
if (index > Capacity)
{
throw new IndexOutOfRangeException();
}
_memoryStream.Position = index;
return (byte) _memoryStream.ReadByte();
}
/// <summary>
/// Relative bulk get method.
///
/// This method transfers bytes from this buffer into the given destination array. If there are fewer bytes
/// remaining in the buffer than are required to satisfy the request, that is, if length > remaining(), then
/// no bytes are transferred and a BufferUnderflowException is thrown.
///
/// Otherwise, this method copies length bytes from this buffer into the given array, starting at the current
/// position of this buffer and at the given offset in the array. The position of this buffer is then
/// incremented by length.
///
/// In other words, an invocation of this method of the form src.get(dst, off, len) has exactly the same effect as the loop
/// <code>
/// for (int i = off; i &lt; off + len; i++)
/// dst[i] = src.get();
/// </code>
/// except that it first checks that there are sufficient bytes in this buffer and it is potentially much more efficient.
/// </summary>
/// <param name="dst"></param>
/// <param name="offset"></param>
/// <param name="length"></param>
/// <returns>This buffer</returns>
internal ByteBuffer Get(byte[] dst, int offset, int length)
{
_memoryStream.Read(dst, offset, length);
return this;
}
/// <summary>
/// Relative bulk get method.
///
/// This method transfers bytes from this buffer into the given destination array.
/// An invocation of this method of the form src.get(a) behaves in exactly the same
/// way as the invocation src.get(a, 0, a.length)
/// </summary>
/// <param name="dst"></param>
/// <returns>This buffer</returns>
internal ByteBuffer Get(byte[] dst)
{
return Get(dst, 0, dst.Length);
}
/// <summary>
/// Sets this buffer's position. If the mark is defined and larger than the new
/// position then it is discarded.
/// </summary>
/// <param name="newPosition">The new position value; must be non-negative and no larger than the current limit</param>
internal void Position(long newPosition)
{
_memoryStream.Position = newPosition;
}
/// <summary>
/// Sets this buffer's limit. If the position is larger than the new limit then it is set to the new limit.
/// If the mark is defined and larger than the new limit then it is discarded.
///
/// A buffer's limit is the index of the first element that should not be read or written. A buffer's limit is never negative and is never greater than its capacity.
/// </summary>
/// <param name="newLimit">The new limit value; must be non-negative and no larger than this buffer's capacity</param>
internal void Limit(long newLimit)
{
_limit = newLimit;
if (_memoryStream.Position > newLimit)
{
_memoryStream.Position = newLimit;
}
}
/// <summary>
/// Returns the number of elements between the current position and the limit.
/// </summary>
/// <returns>The number of elements remaining in this buffer</returns>
internal long Remaining()
{
return (_limit - _memoryStream.Position);
}
/// <summary>
/// Clears this buffer. The position is set to zero, the limit is set to the capacity, and the mark is discarded.
///
/// This method does not actually erase the data in the buffer, but it is named as if
/// it did because it will most often be used in situations in which that might as well be the case.
/// </summary>
internal void Clear()
{
Position(0);
Limit(Capacity);
}
}
}

View File

@@ -0,0 +1,9 @@

namespace Quobject.EngineIoClientDotNet.Parser
{
public interface IDecodePayloadCallback
{
bool Call(Packet packet, int index, int total);
}
}

View File

@@ -0,0 +1,9 @@

namespace Quobject.EngineIoClientDotNet.Parser
{
public interface IEncodeCallback
{
void Call(object data);
}
}

View File

@@ -0,0 +1,408 @@
using Quobject.EngineIoClientDotNet.Modules;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Quobject.EngineIoClientDotNet.Parser
{
/// <remarks>
/// Packet type which is ported from the JavaScript module.
/// This is the JavaScript parser for the engine.io protocol encoding,
/// shared by both engine.io-client and engine.io.
/// <see href="https://github.com/Automattic/engine.io-parser">https://github.com/Automattic/engine.io-parser</see>
/// </remarks>
public class Packet
{
public static readonly string OPEN = "open";
public static readonly string CLOSE = "close";
public static readonly string PING = "ping";
public static readonly string PONG = "pong";
public static readonly string UPGRADE = "upgrade";
public static readonly string MESSAGE = "message";
public static readonly string NOOP = "noop";
public static readonly string ERROR = "error";
private static readonly int MAX_INT_CHAR_LENGTH = int.MaxValue.ToString().Length;
//TODO: suport binary?
private bool SupportsBinary = false;
private static readonly Dictionary<string, byte> _packets = new Dictionary<string, byte>()
{
{Packet.OPEN, 0},
{Packet.CLOSE, 1},
{Packet.PING, 2},
{Packet.PONG, 3},
{Packet.MESSAGE, 4},
{Packet.UPGRADE, 5},
{Packet.NOOP, 6}
};
private static readonly Dictionary<byte, string> _packetsList = new Dictionary<byte, string>();
static Packet()
{
foreach (var entry in _packets)
{
_packetsList.Add(entry.Value,entry.Key);
}
}
private static readonly Packet _err = new Packet(Packet.ERROR,"parser error");
public string Type { get; set; }
public object Data { get; set; }
public Packet(string type, object data)
{
this.Type = type;
this.Data = data;
}
public Packet(string type)
{
this.Type = type;
this.Data = null;
}
internal void Encode(IEncodeCallback callback,bool utf8encode = false)
{
if ( Data is byte[])
{
if (!SupportsBinary)
{
EncodeBase64Packet(callback);
return;
}
EncodeByteArray(callback);
return;
}
var encodedStringBuilder = new StringBuilder();
encodedStringBuilder.Append(_packets[Type]);
if (Data != null)
{
encodedStringBuilder.Append( utf8encode ? UTF8.Encode((string) Data): (string)Data);
}
callback.Call(encodedStringBuilder.ToString());
}
private void EncodeBase64Packet(IEncodeCallback callback)
{
var byteData = Data as byte[];
if (byteData != null)
{
var result = new StringBuilder();
result.Append("b");
result.Append(_packets[Type]);
result.Append(Convert.ToBase64String(byteData));
callback.Call(result.ToString());
return;
}
throw new Exception("byteData == null");
}
private void EncodeByteArray(IEncodeCallback callback)
{
var byteData = Data as byte[];
if (byteData != null)
{
var resultArray = new byte[1 + byteData.Length];
resultArray[0] = _packets[Type];
Array.Copy(byteData, 0, resultArray, 1, byteData.Length);
callback.Call(resultArray);
return;
}
throw new Exception("byteData == null");
}
internal static Packet DecodePacket(string data, bool utf8decode = false)
{
if (data.StartsWith("b"))
{
return DecodeBase64Packet(data.Substring(1));
}
int type;
var s = data.Substring(0, 1);
if (!int.TryParse(s, out type))
{
type = -1;
}
if (utf8decode)
{
try
{
data = UTF8.Decode(data);
}
catch (Exception)
{
return _err;
}
}
if (type < 0 || type >= _packetsList.Count)
{
return _err;
}
if (data.Length > 1)
{
return new Packet(_packetsList[(byte) type], data.Substring(1));
}
return new Packet(_packetsList[(byte) type], null);
}
private static Packet DecodeBase64Packet(string msg)
{
int type;
var s = msg.Substring(0, 1);
if (!int.TryParse(s, out type))
{
type = -1;
}
if (type < 0 || type >= _packetsList.Count)
{
return _err;
}
msg = msg.Substring(1);
byte[] decodedFromBase64 = Convert.FromBase64String(msg);
return new Packet(_packetsList[(byte)type], decodedFromBase64);
}
internal static Packet DecodePacket(byte[] data)
{
int type = data[0];
var byteArray = new byte[data.Length - 1];
Array.Copy(data,1,byteArray,0, byteArray.Length);
return new Packet(_packetsList[(byte)type], byteArray);
}
internal static void EncodePayload(Packet[] packets, IEncodeCallback callback)
{
if (packets.Length == 0)
{
callback.Call(new byte[0]);
return;
}
var results = new List<byte[]>(packets.Length);
var encodePayloadCallback = new EncodePayloadCallback(results);
foreach (var packet in packets)
{
packet.Encode(encodePayloadCallback, true);
}
callback.Call(Buffer.Concat(results.ToArray()));//new byte[results.Count][]
}
/// <summary>
/// Decodes data when a payload is maybe expected.
/// </summary>
/// <param name="data"></param>
/// <param name="callback"></param>
public static void DecodePayload(string data, IDecodePayloadCallback callback)
{
if (String.IsNullOrEmpty(data))
{
callback.Call(_err, 0, 1);
return;
}
var length = new StringBuilder();
for (int i = 0, l = data.Length; i < l; i++)
{
var chr = Convert.ToChar(data.Substring(i, 1));
if (chr != ':')
{
length.Append(chr);
}
else
{
int n;
if (!int.TryParse(length.ToString(), out n))
{
callback.Call(_err, 0, 1);
return;
}
string msg;
try
{
msg = data.Substring(i + 1, n);
}
catch (ArgumentOutOfRangeException)
{
callback.Call(_err, 0, 1);
return;
}
if (msg.Length != 0)
{
Packet packet = DecodePacket(msg, true);
if (_err.Type == packet.Type && _err.Data == packet.Data)
{
callback.Call(_err, 0, 1);
return;
}
bool ret = callback.Call(packet, i + n, l);
if (!ret)
{
return;
}
}
i += n;
length = new StringBuilder();
}
}
if (length.Length > 0)
{
callback.Call(_err, 0, 1);
}
}
/// <summary>
/// Decodes data when a payload is maybe expected.
/// </summary>
/// <param name="data"></param>
/// <param name="callback"></param>
public static void DecodePayload(byte[] data, IDecodePayloadCallback callback)
{
var bufferTail = ByteBuffer.Wrap(data);
var buffers = new List<object>();
int bufferTail_offset = 0;
while (bufferTail.Capacity - bufferTail_offset > 0)
{
var strLen = new StringBuilder();
var isString = (bufferTail.Get(0 + bufferTail_offset) & 0xFF) == 0;
var numberTooLong = false;
for (int i = 1;; i++)
{
int b = bufferTail.Get(i + bufferTail_offset) & 0xFF;
if (b == 255)
{
break;
}
// support only integer
if (strLen.Length > MAX_INT_CHAR_LENGTH)
{
numberTooLong = true;
break;
}
strLen.Append(b);
}
if (numberTooLong)
{
callback.Call(_err, 0, 1);
return;
}
bufferTail_offset += strLen.Length + 1;
int msgLength = int.Parse(strLen.ToString());
bufferTail.Position(1 + bufferTail_offset);
bufferTail.Limit(msgLength + 1 + bufferTail_offset);
var msg = new byte[bufferTail.Remaining()];
bufferTail.Get(msg, 0, msg.Length);
if (isString)
{
buffers.Add(ByteArrayToString(msg));
}
else
{
buffers.Add(msg);
}
bufferTail.Clear();
bufferTail.Position(msgLength + 1 + bufferTail_offset);
bufferTail_offset += msgLength + 1;
}
var total = buffers.Count;
for (int i = 0; i < total; i++)
{
var buffer = buffers[i];
if (buffer is string)
{
callback.Call(DecodePacket((string) buffer, true), i, total);
}
else if (buffer is byte[])
{
callback.Call(DecodePacket((byte[])buffer), i, total);
}
}
}
internal static byte[] StringToByteArray(string str)
{
int len = str.Length;
var bytes = new byte[len];
for (int i = 0; i < len; i++)
{
bytes[i] = (byte)str[i];
}
return bytes;
}
internal static string ByteArrayToString(byte[] bytes)
{
//return Encoding.ASCII.GetString(bytes);
//http://stackoverflow.com/questions/7750850/encoding-ascii-getstring-in-windows-phone-platform
return string.Concat(bytes.Select(b => b <= 0x7f ? (char)b : '?'));
}
private class EncodePayloadCallback : IEncodeCallback
{
private readonly List<byte[]> _results;
public EncodePayloadCallback(List<byte[]> results)
{
this._results = results;
}
public void Call(object data)
{
if (data is string)
{
var packet = (string) data;
var encodingLength = packet.Length.ToString();
var sizeBuffer = new byte[encodingLength.Length + 2];
sizeBuffer[0] = (byte) 0; // is a string
for (var i = 0; i < encodingLength.Length; i++)
{
sizeBuffer[i + 1] = byte.Parse(encodingLength.Substring(i,1));
}
sizeBuffer[sizeBuffer.Length - 1] = (byte) 255;
_results.Add(Buffer.Concat(new byte[][] { sizeBuffer, StringToByteArray(packet) }));
return;
}
var packet1 = (byte[]) data;
var encodingLength1 = packet1.Length.ToString();
var sizeBuffer1 = new byte[encodingLength1.Length + 2];
sizeBuffer1[0] = (byte)1; // is binary
for (var i = 0; i < encodingLength1.Length; i++)
{
sizeBuffer1[i + 1] = byte.Parse(encodingLength1.Substring(i, 1));
}
sizeBuffer1[sizeBuffer1.Length - 1] = (byte)255;
_results.Add(Buffer.Concat(new byte[][] { sizeBuffer1, packet1 }));
}
}
}
}

View File

@@ -0,0 +1,412 @@
using Quobject.EngineIoClientDotNet.Modules;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Quobject.EngineIoClientDotNet.Parser
{
/// <remarks>
/// Packet type which is ported from the JavaScript module.
/// This is the JavaScript parser for the engine.io protocol encoding,
/// shared by both engine.io-client and engine.io.
/// <see href="https://github.com/Automattic/engine.io-parser">https://github.com/Automattic/engine.io-parser</see>
/// </remarks>
public class Packet
{
public static readonly string OPEN = "open";
public static readonly string CLOSE = "close";
public static readonly string PING = "ping";
public static readonly string PONG = "pong";
public static readonly string UPGRADE = "upgrade";
public static readonly string MESSAGE = "message";
public static readonly string NOOP = "noop";
public static readonly string ERROR = "error";
private static readonly int MAX_INT_CHAR_LENGTH = int.MaxValue.ToString().Length;
//TODO: suport binary?
private bool SupportsBinary = false;
private static readonly Dictionary<string, byte> _packets = new Dictionary<string, byte>()
{
{Packet.OPEN, 0},
{Packet.CLOSE, 1},
{Packet.PING, 2},
{Packet.PONG, 3},
{Packet.MESSAGE, 4},
{Packet.UPGRADE, 5},
{Packet.NOOP, 6}
};
private static readonly Dictionary<byte, string> _packetsList = new Dictionary<byte, string>();
static Packet()
{
foreach (var entry in _packets)
{
_packetsList.Add(entry.Value,entry.Key);
}
}
private static readonly Packet _err = new Packet(Packet.ERROR,"parser error");
public string Type { get; set; }
public object Data { get; set; }
public Packet(string type, object data)
{
this.Type = type;
this.Data = data;
}
public Packet(string type)
{
this.Type = type;
this.Data = null;
}
internal void Encode(IEncodeCallback callback,bool utf8encode = false)
{
if ( Data is byte[])
{
if (!SupportsBinary)
{
EncodeBase64Packet(callback);
return;
}
EncodeByteArray(callback);
return;
}
var encodedStringBuilder = new StringBuilder();
encodedStringBuilder.Append(_packets[Type]);
if (Data != null)
{
encodedStringBuilder.Append( utf8encode ? UTF8.Encode((string) Data): (string)Data);
}
callback.Call(encodedStringBuilder.ToString());
}
private void EncodeBase64Packet(IEncodeCallback callback)
{
var byteData = Data as byte[];
if (byteData != null)
{
var result = new StringBuilder();
result.Append("b");
result.Append(_packets[Type]);
result.Append(Convert.ToBase64String(byteData));
callback.Call(result.ToString());
return;
}
throw new Exception("byteData == null");
}
private void EncodeByteArray(IEncodeCallback callback)
{
var byteData = Data as byte[];
if (byteData != null)
{
var resultArray = new byte[1 + byteData.Length];
resultArray[0] = _packets[Type];
Array.Copy(byteData, 0, resultArray, 1, byteData.Length);
callback.Call(resultArray);
return;
}
throw new Exception("byteData == null");
}
internal static Packet DecodePacket(string data, bool utf8decode = false)
{
if (data.StartsWith("b"))
{
return DecodeBase64Packet(data.Substring(1));
}
int type;
var s = data.Substring(0, 1);
if (!int.TryParse(s, out type))
{
type = -1;
}
if (utf8decode)
{
try
{
data = UTF8.Decode(data);
}
catch (Exception)
{
return _err;
}
}
if (type < 0 || type >= _packetsList.Count)
{
return _err;
}
if (data.Length > 1)
{
return new Packet(_packetsList[(byte) type], data.Substring(1));
}
return new Packet(_packetsList[(byte) type], null);
}
private static Packet DecodeBase64Packet(string msg)
{
int type;
var s = msg.Substring(0, 1);
if (!int.TryParse(s, out type))
{
type = -1;
}
if (type < 0 || type >= _packetsList.Count)
{
return _err;
}
msg = msg.Substring(1);
byte[] decodedFromBase64 = Convert.FromBase64String(msg);
return new Packet(_packetsList[(byte)type], decodedFromBase64);
}
internal static Packet DecodePacket(byte[] data)
{
int type = data[0];
var byteArray = new byte[data.Length - 1];
Array.Copy(data,1,byteArray,0, byteArray.Length);
return new Packet(_packetsList[(byte)type], byteArray);
}
internal static void EncodePayload(Packet[] packets, IEncodeCallback callback)
{
if (packets.Length == 0)
{
callback.Call(new byte[0]);
return;
}
var results = new List<byte[]>(packets.Length);
var encodePayloadCallback = new EncodePayloadCallback(results);
foreach (var packet in packets)
{
packet.Encode(encodePayloadCallback, true);
}
callback.Call(Buffer.Concat(results.ToArray()));//new byte[results.Count][]
}
/// <summary>
/// Decodes data when a payload is maybe expected.
/// </summary>
/// <param name="data"></param>
/// <param name="callback"></param>
public static void DecodePayload(string data, IDecodePayloadCallback callback)
{
if (String.IsNullOrEmpty(data))
{
callback.Call(_err, 0, 1);
return;
}
var length = new StringBuilder();
for (int i = 0, l = data.Length; i < l; i++)
{
var chr = Convert.ToChar(data.Substring(i, 1));
if (chr != ':')
{
length.Append(chr);
}
else
{
int n;
if (!int.TryParse(length.ToString(), out n))
{
callback.Call(_err, 0, 1);
return;
}
string msg;
try
{
msg = data.Substring(i + 1, n);
}
catch (ArgumentOutOfRangeException)
{
callback.Call(_err, 0, 1);
return;
}
if (msg.Length != 0)
{
Packet packet = DecodePacket(msg, true);
if (_err.Type == packet.Type && _err.Data == packet.Data)
{
callback.Call(_err, 0, 1);
return;
}
bool ret = callback.Call(packet, i + n, l);
if (!ret)
{
return;
}
}
i += n;
length = new StringBuilder();
}
}
if (length.Length > 0)
{
callback.Call(_err, 0, 1);
}
}
/// <summary>
/// Decodes data when a payload is maybe expected.
/// </summary>
/// <param name="data"></param>
/// <param name="callback"></param>
public static void DecodePayload(byte[] data, IDecodePayloadCallback callback)
{
var bufferTail = ByteBuffer.Wrap(data);
var buffers = new List<object>();
int bufferTail_offset = 0;
while (bufferTail.Capacity - bufferTail_offset > 0)
{
var strLen = new StringBuilder();
var isString = (bufferTail.Get(0 + bufferTail_offset) & 0xFF) == 0;
var numberTooLong = false;
for (int i = 1;; i++)
{
int b = bufferTail.Get(i + bufferTail_offset) & 0xFF;
if (b == 255)
{
break;
}
// support only integer
if (strLen.Length > MAX_INT_CHAR_LENGTH)
{
numberTooLong = true;
break;
}
strLen.Append(b);
}
if (numberTooLong)
{
callback.Call(_err, 0, 1);
return;
}
bufferTail_offset += strLen.Length + 1;
int msgLength = int.Parse(strLen.ToString());
bufferTail.Position(1 + bufferTail_offset);
bufferTail.Limit(msgLength + 1 + bufferTail_offset);
var msg = new byte[bufferTail.Remaining()];
bufferTail.Get(msg, 0, msg.Length);
if (isString)
{
buffers.Add(ByteArrayToString(msg));
}
else
{
buffers.Add(msg);
}
bufferTail.Clear();
bufferTail.Position(msgLength + 1 + bufferTail_offset);
bufferTail_offset += msgLength + 1;
}
var total = buffers.Count;
for (int i = 0; i < total; i++)
{
var buffer = buffers[i];
if (buffer is string)
{
callback.Call(DecodePacket((string) buffer, true), i, total);
}
else if (buffer is byte[])
{
callback.Call(DecodePacket((byte[])buffer), i, total);
}
}
}
internal static byte[] StringToByteArray(string str)
{
int len = str.Length;
var bytes = new byte[len];
for (int i = 0; i < len; i++)
{
bytes[i] = (byte)str[i];
}
return bytes;
}
internal static string ByteArrayToString(byte[] bytes)
{
//return Encoding.ASCII.GetString(bytes);
//http://stackoverflow.com/questions/7750850/encoding-ascii-getstring-in-windows-phone-platform
// return string.Concat(bytes.Select(b => b <= 0x7f ? (char)b : '?')); //.net 4.0 only
return string.Concat(
(bytes.Select(b => (b <= 0x7f ? (char) b : '?').ToString()))
.ToArray()
);
}
private class EncodePayloadCallback : IEncodeCallback
{
private readonly List<byte[]> _results;
public EncodePayloadCallback(List<byte[]> results)
{
this._results = results;
}
public void Call(object data)
{
if (data is string)
{
var packet = (string) data;
var encodingLength = packet.Length.ToString();
var sizeBuffer = new byte[encodingLength.Length + 2];
sizeBuffer[0] = (byte) 0; // is a string
for (var i = 0; i < encodingLength.Length; i++)
{
sizeBuffer[i + 1] = byte.Parse(encodingLength.Substring(i,1));
}
sizeBuffer[sizeBuffer.Length - 1] = (byte) 255;
_results.Add(Buffer.Concat(new byte[][] { sizeBuffer, StringToByteArray(packet) }));
return;
}
var packet1 = (byte[]) data;
var encodingLength1 = packet1.Length.ToString();
var sizeBuffer1 = new byte[encodingLength1.Length + 2];
sizeBuffer1[0] = (byte)1; // is binary
for (var i = 0; i < encodingLength1.Length; i++)
{
sizeBuffer1[i + 1] = byte.Parse(encodingLength1.Substring(i, 1));
}
sizeBuffer1[sizeBuffer1.Length - 1] = (byte)255;
_results.Add(Buffer.Concat(new byte[][] { sizeBuffer1, packet1 }));
}
}
}
}

View File

@@ -0,0 +1,51 @@

namespace Quobject.EngineIoClientDotNet.Parser
{
/// <remarks>
/// This is the JavaScript parser for the engine.io protocol encoding,
/// shared by both engine.io-client and engine.io.
/// <see href="https://github.com/Automattic/engine.io-parser">https://github.com/Automattic/engine.io-parser</see>
/// </remarks>
public class Parser
{
public static readonly int Protocol = 3;
private Parser()
{
}
public static void EncodePacket(Packet packet, IEncodeCallback callback)
{
packet.Encode(callback);
}
public static Packet DecodePacket(string data, bool utf8decode = false)
{
return Packet.DecodePacket(data, utf8decode);
}
public static Packet DecodePacket(byte[] data)
{
return Packet.DecodePacket(data);
}
public static void EncodePayload(Packet[] packets, IEncodeCallback callback)
{
Packet.EncodePayload(packets, callback);
}
public static void DecodePayload(string data, IDecodePayloadCallback callback)
{
Packet.DecodePayload(data, callback);
}
public static void DecodePayload(byte[] data, IDecodePayloadCallback callback)
{
Packet.DecodePayload(data, callback);
}
}
}

View File

@@ -0,0 +1,35 @@
using System.Reflection;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("EngineIoClientDotNet")]
[assembly: AssemblyDescription("Engine.IO Client Library for .Net")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Quobject Software")]
[assembly: AssemblyProduct("EngineIoClientDotNet")]
[assembly: AssemblyCopyright("Copyright © 2014")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("a95e75cd-35e6-4e88-9e22-631e3fd01546")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("0.9.4")]
[assembly: AssemblyFileVersion("0.9.4")]

View File

@@ -0,0 +1,62 @@

using System;
using System.Threading;
using System.Threading.Tasks;
namespace Quobject.EngineIoClientDotNet.Thread
{
public class EasyTimer
{
private CancellationTokenSource ts;
public EasyTimer(CancellationTokenSource ts)
{
this.ts = ts;
}
public static EasyTimer SetTimeout(Action method, int delayInMilliseconds)
{
var ts = new CancellationTokenSource();
CancellationToken ct = ts.Token;
var task = Task.Delay(delayInMilliseconds,ct);
var awaiter = task.GetAwaiter();
awaiter.OnCompleted(
() =>
{
if (!ts.IsCancellationRequested)
{
method();
}
});
// Returns a stop handle which can be used for stopping
// the timer, if required
return new EasyTimer(ts);
}
public void Stop()
{
//var log = LogManager.GetLogger(Global.CallerName());
//log.Info("EasyTimer stop");
if (ts != null)
{
ts.Cancel();
}
}
public static void TaskRun(Action action)
{
Task.Run(action).Wait();
}
public static void TaskRunNoWait(Action action)
{
Task.Run(action);
}
}
}

View File

@@ -0,0 +1,76 @@

using System.ComponentModel;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
using Quobject.EngineIoClientDotNet.Modules;
using System;
namespace Quobject.EngineIoClientDotNet.Thread
{
public class EasyTimer
{
private CancellationTokenSource ts;
public EasyTimer(CancellationTokenSource ts)
{
this.ts = ts;
}
public static EasyTimer SetTimeout(Action method, int delayInMilliseconds)
{
var ts = new CancellationTokenSource();
var ct = ts.Token;
var worker = new BackgroundWorker();
worker.DoWork += (s, e) => System.Threading.Thread.Sleep(delayInMilliseconds);
worker.RunWorkerCompleted += (s, e) =>
{
if (!ts.IsCancellationRequested)
{
Task.Factory.StartNew(method, ct, TaskCreationOptions.None, TaskScheduler.Default);
}
};
worker.RunWorkerAsync();
// Returns a stop handle which can be used for stopping
// the timer, if required
return new EasyTimer(ts);
}
public void Stop()
{
var log = LogManager.GetLogger(Global.CallerName());
log.Info("EasyTimer stop");
if (ts != null)
{
ts.Cancel();
}
}
public static void TaskRun(Action action)
{
Task.Run(action).Wait();
}
public static Task TaskRunNoWait(Action action)
{
return Task.Run(action);
}
}
}

View File

@@ -0,0 +1,88 @@

using System.ComponentModel;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
using Quobject.EngineIoClientDotNet.Modules;
using System;
namespace Quobject.EngineIoClientDotNet.Thread
{
public class EasyTimer
{
private CancellationTokenSource ts;
public EasyTimer(CancellationTokenSource ts)
{
this.ts = ts;
}
public static EasyTimer SetTimeout(Action method, int delayInMilliseconds)
{
var ts = new CancellationTokenSource();
var ct = ts.Token;
var worker = new BackgroundWorker();
worker.DoWork += (s, e) => System.Threading.Thread.Sleep(delayInMilliseconds);
worker.RunWorkerCompleted += (s, e) =>
{
if (!ts.IsCancellationRequested)
{
Task.Factory.StartNew(method, ct, TaskCreationOptions.None, TaskScheduler.Default);
}
};
worker.RunWorkerAsync();
// Returns a stop handle which can be used for stopping
// the timer, if required
return new EasyTimer(ts);
}
public void Stop()
{
var log = LogManager.GetLogger(Global.CallerName());
log.Info("EasyTimer stop");
if (ts != null)
{
ts.Cancel();
}
}
public static void TaskRun(Action action)
{
var t = new Task(action);
t.RunSynchronously();
if (t.IsFaulted)
{
if (t.Exception != null)
{
throw t.Exception;
}
throw new Exception();
}
//Task.Run(action).Wait();
}
public static Task TaskRunNoWait(Action action)
{
var t = new Task(action);
t.Start();
return t;
}
}
}

View File

@@ -0,0 +1,55 @@
using System;
using System.ComponentModel;
using System.Threading;
namespace Quobject.EngineIoClientDotNet.Thread
{
public class Heartbeat
{
private volatile bool gotHeartbeat = false;
private BackgroundWorker heartBeatTimer;
private CancellationTokenSource ts;
private Heartbeat()
{
ts = new CancellationTokenSource();
}
public static Heartbeat Start(Action onTimeout, int timeout)
{
Heartbeat heartbeat = new Heartbeat();
heartbeat.Run(onTimeout, timeout);
return heartbeat;
}
public void OnHeartbeat()
{
gotHeartbeat = true;
}
private void Run(Action onTimeout, int timeout)
{
heartBeatTimer = new BackgroundWorker();
heartBeatTimer.DoWork += (s, e) =>
{
while (!ts.IsCancellationRequested)
{
System.Threading.Thread.Sleep(timeout);
if (!gotHeartbeat && !ts.IsCancellationRequested)
{
onTimeout();
break;
}
}
};
heartBeatTimer.RunWorkerAsync();
}
public void Stop()
{
ts.Cancel();
}
}
}

View File

@@ -0,0 +1,61 @@
using System;
using System.ComponentModel;
using System.Threading;
namespace Quobject.EngineIoClientDotNet.Thread
{
public class TriggeredLoopTimer
{
private ManualResetEvent trigger;
private CancellationTokenSource ts;
private TriggeredLoopTimer()
{
trigger = new ManualResetEvent(false);
ts = new CancellationTokenSource();
}
public static TriggeredLoopTimer Start (Action method, int delayInMilliseconds)
{
TriggeredLoopTimer ping = new TriggeredLoopTimer();
ping.Run (method, delayInMilliseconds);
return ping;
}
public void Trigger()
{
trigger.Set();
}
private void Run (Action method, int delayInMilliseconds)
{
var worker = new BackgroundWorker();
worker.DoWork += (s, e) =>
{
while (!ts.IsCancellationRequested)
{
System.Threading.Thread.Sleep (delayInMilliseconds);
if (!ts.IsCancellationRequested)
{
method();
trigger.WaitOne();
trigger.Reset();
}
}
};
worker.RunWorkerAsync();
}
public void Stop()
{
if (ts != null)
{
ts.Cancel();
trigger.Set();
}
}
}
}

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Newtonsoft.Json" version="10.0.1" targetFramework="net45" />
<package id="SuperSocket.ClientEngine.Core" version="0.8.0.8" targetFramework="net45" />
<package id="WebSocket4Net" version="0.15.0-beta6" targetFramework="net45" />
</packages>

View File

@@ -0,0 +1,137 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{568D67D0-3253-4601-9B04-7730A9EC5CC0}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>EngineIoClientDotNet</RootNamespace>
<AssemblyName>EngineIoClientDotNet</AssemblyName>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<NuGetPackageImportStamp>daa4bcba</NuGetPackageImportStamp>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\net35\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>packages\Newtonsoft.Json.9.0.1\lib\net35\Newtonsoft.Json.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="SuperSocket.ClientEngine, Version=0.9.0.0, Culture=neutral, PublicKeyToken=ee9af13f57f00acc, processorArchitecture=MSIL">
<HintPath>packages\SuperSocket.ClientEngine.Core.0.9.0\lib\net35-client\SuperSocket.ClientEngine.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Threading.Tasks.NET35, Version=3.0.2.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>packages\System.Threading.Tasks.Unofficial.3.1\lib\net35\System.Threading.Tasks.NET35.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
<Reference Include="WebSocket4Net, Version=0.15.1.10, Culture=neutral, PublicKeyToken=eb4e154b696bf72a, processorArchitecture=MSIL">
<HintPath>packages\WebSocket4Net.0.15.1\lib\net35\WebSocket4Net.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="..\EngineIoClientDotNet.mono\Client\EngineIOException.cs">
<Link>Client\EngineIOException.cs</Link>
</Compile>
<Compile Include="..\EngineIoClientDotNet.mono\Client\HandshakeData_net35.cs">
<Link>Client\HandshakeData_net35.cs</Link>
</Compile>
<Compile Include="..\EngineIoClientDotNet.mono\Client\Socket_net35.cs">
<Link>Client\Socket_net35.cs</Link>
</Compile>
<Compile Include="..\EngineIoClientDotNet.mono\Client\Transports\PollingXHR_net35.cs">
<Link>Client\Transports\PollingXHR_net35.cs</Link>
</Compile>
<Compile Include="..\EngineIoClientDotNet.mono\Client\Transports\Polling_net35.cs">
<Link>Client\Transports\Polling_net35.cs</Link>
</Compile>
<Compile Include="..\EngineIoClientDotNet.mono\Client\Transports\WebSocket_net35.cs">
<Link>Client\Transports\WebSocket_net35.cs</Link>
</Compile>
<Compile Include="..\EngineIoClientDotNet.mono\Client\Transport_net35.cs">
<Link>Client\Transport_net35.cs</Link>
</Compile>
<Compile Include="..\EngineIoClientDotNet.mono\ComponentEmitter\Emitter_net35.cs">
<Link>ComponentEmitter\Emitter_net35.cs</Link>
</Compile>
<Compile Include="..\EngineIoClientDotNet.mono\Modules\Global_net35.cs">
<Link>Modules\Global_net35.cs</Link>
</Compile>
<Compile Include="..\EngineIoClientDotNet.mono\Modules\LogManager.cs">
<Link>Modules\LogManager.cs</Link>
</Compile>
<Compile Include="..\EngineIoClientDotNet.mono\Modules\ParseQS_net35.cs">
<Link>Modules\ParseQS_net35.cs</Link>
</Compile>
<Compile Include="..\EngineIoClientDotNet.mono\Modules\ServerCertificate.cs">
<Link>Modules\ServerCertificate.cs</Link>
</Compile>
<Compile Include="..\EngineIoClientDotNet.mono\Modules\UTF8.cs">
<Link>Modules\UTF8.cs</Link>
</Compile>
<Compile Include="..\EngineIoClientDotNet.mono\Modules\UTF8Exception.cs">
<Link>Modules\UTF8Exception.cs</Link>
</Compile>
<Compile Include="..\EngineIoClientDotNet.mono\Parser\Buffer.cs">
<Link>Parser\Buffer.cs</Link>
</Compile>
<Compile Include="..\EngineIoClientDotNet.mono\Parser\ByteBuffer.cs">
<Link>Parser\ByteBuffer.cs</Link>
</Compile>
<Compile Include="..\EngineIoClientDotNet.mono\Parser\IDecodePayloadCallback.cs">
<Link>Parser\IDecodePayloadCallback.cs</Link>
</Compile>
<Compile Include="..\EngineIoClientDotNet.mono\Parser\IEncodeCallback.cs">
<Link>Parser\IEncodeCallback.cs</Link>
</Compile>
<Compile Include="..\EngineIoClientDotNet.mono\Parser\Parser.cs">
<Link>Parser\Parser.cs</Link>
</Compile>
<Compile Include="..\EngineIoClientDotNet.mono\Thread\EasyTimer_net35.cs">
<Link>Thread\EasyTimer_net35.cs</Link>
</Compile>
<Compile Include="..\EngineIoClientDotNet.mono\Thread\Heartbeat_net35.cs">
<Link>Thread\Heartbeat_net35.cs</Link>
</Compile>
<Compile Include="..\EngineIoClientDotNet.mono\Thread\TriggeredLoopTimer_net35.cs">
<Link>Thread\TriggeredLoopTimer_net35.cs</Link>
</Compile>
<Compile Include="Parser\Packet_net35.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

Some files were not shown because too many files have changed in this diff Show More