Added WebSocketSharp support and fixed Mono issues
This commit is contained in:
@@ -59,6 +59,9 @@
|
|||||||
<Reference Include="RestSharp, Version=105.2.3.0, Culture=neutral, PublicKeyToken=null">
|
<Reference Include="RestSharp, Version=105.2.3.0, Culture=neutral, PublicKeyToken=null">
|
||||||
<HintPath>..\..\..\DiscordBot\packages\RestSharp.105.2.3\lib\net45\RestSharp.dll</HintPath>
|
<HintPath>..\..\..\DiscordBot\packages\RestSharp.105.2.3\lib\net45\RestSharp.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
|
<Reference Include="websocket-sharp, Version=1.0.2.36589, Culture=neutral, PublicKeyToken=5660b08a1845a91e">
|
||||||
|
<HintPath>..\..\..\DiscordBot\packages\WebSocketSharp.1.0.3-rc9\lib\websocket-sharp.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Content Include="lib\libopus.so" />
|
<Content Include="lib\libopus.so" />
|
||||||
@@ -241,6 +244,9 @@
|
|||||||
<Compile Include="..\Discord.Net\WebSockets\WebSocket.Events.cs">
|
<Compile Include="..\Discord.Net\WebSockets\WebSocket.Events.cs">
|
||||||
<Link>WebSockets\WebSocket.Events.cs</Link>
|
<Link>WebSockets\WebSocket.Events.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="..\Discord.Net\WebSockets\WebSocket.WebSocketSharp.cs">
|
||||||
|
<Link>WebSockets\WebSocket.WebSocketSharp.cs</Link>
|
||||||
|
</Compile>
|
||||||
<Compile Include="..\Discord.Net\WebSockets\WebSocketMessage.cs">
|
<Compile Include="..\Discord.Net\WebSockets\WebSocketMessage.cs">
|
||||||
<Link>WebSockets\WebSocketMessage.cs</Link>
|
<Link>WebSockets\WebSocketMessage.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
|||||||
@@ -2,4 +2,5 @@
|
|||||||
<packages>
|
<packages>
|
||||||
<package id="Newtonsoft.Json" version="7.0.1" targetFramework="net45" />
|
<package id="Newtonsoft.Json" version="7.0.1" targetFramework="net45" />
|
||||||
<package id="RestSharp" version="105.2.3" targetFramework="net45" />
|
<package id="RestSharp" version="105.2.3" targetFramework="net45" />
|
||||||
|
<package id="WebSocketSharp" version="1.0.3-rc9" targetFramework="net45" />
|
||||||
</packages>
|
</packages>
|
||||||
@@ -40,7 +40,7 @@ namespace Discord.WebSockets.Data
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var cancelToken = ParentCancelToken;
|
var cancelToken = ParentCancelToken.Value;
|
||||||
await Task.Delay(_client.Config.ReconnectDelay, cancelToken).ConfigureAwait(false);
|
await Task.Delay(_client.Config.ReconnectDelay, cancelToken).ConfigureAwait(false);
|
||||||
while (!cancelToken.IsCancellationRequested)
|
while (!cancelToken.IsCancellationRequested)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ namespace Discord.WebSockets.Voice
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var cancelToken = ParentCancelToken;
|
var cancelToken = ParentCancelToken.Value;
|
||||||
await Task.Delay(_client.Config.ReconnectDelay, cancelToken).ConfigureAwait(false);
|
await Task.Delay(_client.Config.ReconnectDelay, cancelToken).ConfigureAwait(false);
|
||||||
while (!cancelToken.IsCancellationRequested)
|
while (!cancelToken.IsCancellationRequested)
|
||||||
{
|
{
|
||||||
@@ -127,7 +127,8 @@ namespace Discord.WebSockets.Voice
|
|||||||
{
|
{
|
||||||
#if USE_THREAD
|
#if USE_THREAD
|
||||||
_sendThread = new Thread(new ThreadStart(() => SendVoiceAsync(_cancelToken)));
|
_sendThread = new Thread(new ThreadStart(() => SendVoiceAsync(_cancelToken)));
|
||||||
_sendThread.Start();
|
_sendThread.IsBackground = true;
|
||||||
|
_sendThread.Start();
|
||||||
#else
|
#else
|
||||||
tasks.Add(SendVoiceAsync());
|
tasks.Add(SendVoiceAsync());
|
||||||
#endif
|
#endif
|
||||||
@@ -138,6 +139,7 @@ namespace Discord.WebSockets.Voice
|
|||||||
if ((_client.Config.VoiceMode & DiscordVoiceMode.Incoming) != 0)
|
if ((_client.Config.VoiceMode & DiscordVoiceMode.Incoming) != 0)
|
||||||
{
|
{
|
||||||
_receiveThread = new Thread(new ThreadStart(() => ReceiveVoiceAsync(_cancelToken)));
|
_receiveThread = new Thread(new ThreadStart(() => ReceiveVoiceAsync(_cancelToken)));
|
||||||
|
_sendThread.IsBackground = true;
|
||||||
_receiveThread.Start();
|
_receiveThread.Start();
|
||||||
}
|
}
|
||||||
else //Dont make an OS thread if we only want to capture one packet...
|
else //Dont make an OS thread if we only want to capture one packet...
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Discord.Helpers;
|
#if DNXCORE50
|
||||||
|
using Discord.Helpers;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
@@ -16,7 +17,7 @@ namespace Discord.WebSockets
|
|||||||
private const int SendChunkSize = 4096;
|
private const int SendChunkSize = 4096;
|
||||||
private const int HR_TIMEOUT = -2147012894;
|
private const int HR_TIMEOUT = -2147012894;
|
||||||
|
|
||||||
private readonly ConcurrentQueue<byte[]> _sendQueue;
|
private readonly ConcurrentQueue<string> _sendQueue;
|
||||||
private readonly int _sendInterval;
|
private readonly int _sendInterval;
|
||||||
private ClientWebSocket _webSocket;
|
private ClientWebSocket _webSocket;
|
||||||
|
|
||||||
@@ -30,7 +31,7 @@ namespace Discord.WebSockets
|
|||||||
public BuiltInWebSocketEngine(int sendInterval)
|
public BuiltInWebSocketEngine(int sendInterval)
|
||||||
{
|
{
|
||||||
_sendInterval = sendInterval;
|
_sendInterval = sendInterval;
|
||||||
_sendQueue = new ConcurrentQueue<byte[]>();
|
_sendQueue = new ConcurrentQueue<string>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task Connect(string host, CancellationToken cancelToken)
|
public Task Connect(string host, CancellationToken cancelToken)
|
||||||
@@ -42,7 +43,7 @@ namespace Discord.WebSockets
|
|||||||
|
|
||||||
public Task Disconnect()
|
public Task Disconnect()
|
||||||
{
|
{
|
||||||
byte[] ignored;
|
string ignored;
|
||||||
while (_sendQueue.TryDequeue(out ignored)) { }
|
while (_sendQueue.TryDequeue(out ignored)) { }
|
||||||
_webSocket.Dispose();
|
_webSocket.Dispose();
|
||||||
_webSocket = new ClientWebSocket();
|
_webSocket = new ClientWebSocket();
|
||||||
@@ -107,12 +108,13 @@ namespace Discord.WebSockets
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
byte[] bytes;
|
|
||||||
while (_webSocket.State == State.Open && !cancelToken.IsCancellationRequested)
|
while (_webSocket.State == State.Open && !cancelToken.IsCancellationRequested)
|
||||||
{
|
{
|
||||||
while (_sendQueue.TryDequeue(out bytes))
|
string json;
|
||||||
|
while (_sendQueue.TryDequeue(out json))
|
||||||
{
|
{
|
||||||
var frameCount = (int)Math.Ceiling((double)bytes.Length / SendChunkSize);
|
byte[] bytes = Encoding.UTF8.GetBytes(json);
|
||||||
|
int frameCount = (int)Math.Ceiling((double)bytes.Length / SendChunkSize);
|
||||||
|
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
for (var i = 0; i < frameCount; i++, offset += SendChunkSize)
|
for (var i = 0; i < frameCount; i++, offset += SendChunkSize)
|
||||||
@@ -142,9 +144,10 @@ namespace Discord.WebSockets
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void QueueMessage(byte[] message)
|
public void QueueMessage(string message)
|
||||||
{
|
{
|
||||||
_sendQueue.Enqueue(message);
|
_sendQueue.Enqueue(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
88
src/Discord.Net/WebSockets/WebSocket.WebSocketSharp.cs
Normal file
88
src/Discord.Net/WebSockets/WebSocket.WebSocketSharp.cs
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
#if !DNXCORE50
|
||||||
|
using Discord.Helpers;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using WSSharpNWebSocket = WebSocketSharp.WebSocket;
|
||||||
|
|
||||||
|
namespace Discord.WebSockets
|
||||||
|
{
|
||||||
|
public class WSSharpWebSocketEngine : IWebSocketEngine
|
||||||
|
{
|
||||||
|
private readonly ConcurrentQueue<string> _sendQueue;
|
||||||
|
private readonly int _sendInterval;
|
||||||
|
private readonly string _userAgent;
|
||||||
|
private readonly WebSocket _parent;
|
||||||
|
private WSSharpNWebSocket _webSocket;
|
||||||
|
|
||||||
|
public event EventHandler<WebSocketMessageEventArgs> ProcessMessage;
|
||||||
|
private void RaiseProcessMessage(string msg)
|
||||||
|
{
|
||||||
|
if (ProcessMessage != null)
|
||||||
|
ProcessMessage(this, new WebSocketMessageEventArgs(msg));
|
||||||
|
}
|
||||||
|
|
||||||
|
internal WSSharpWebSocketEngine(WebSocket parent, string userAgent, int sendInterval)
|
||||||
|
{
|
||||||
|
_parent = parent;
|
||||||
|
_userAgent = userAgent;
|
||||||
|
_sendInterval = sendInterval;
|
||||||
|
_sendQueue = new ConcurrentQueue<string>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task Connect(string host, CancellationToken cancelToken)
|
||||||
|
{
|
||||||
|
_webSocket = new WSSharpNWebSocket(host);
|
||||||
|
_webSocket.EmitOnPing = false;
|
||||||
|
_webSocket.EnableRedirection = true;
|
||||||
|
_webSocket.Compression = WebSocketSharp.CompressionMethod.None;
|
||||||
|
_webSocket.OnMessage += (s, e) => RaiseProcessMessage(e.Data);
|
||||||
|
_webSocket.OnError += (s, e) => _parent.RaiseOnLog(LogMessageSeverity.Error, $"Websocket Error: {e.Message}");
|
||||||
|
_webSocket.Connect();
|
||||||
|
return TaskHelper.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task Disconnect()
|
||||||
|
{
|
||||||
|
string ignored;
|
||||||
|
while (_sendQueue.TryDequeue(out ignored)) { }
|
||||||
|
_webSocket.Close();
|
||||||
|
return TaskHelper.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task[] GetTasks(CancellationToken cancelToken)
|
||||||
|
{
|
||||||
|
return new Task[]
|
||||||
|
{
|
||||||
|
SendAsync(cancelToken)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private Task SendAsync(CancellationToken cancelToken)
|
||||||
|
{
|
||||||
|
return Task.Run(async () =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
while (_webSocket.IsAlive && !cancelToken.IsCancellationRequested)
|
||||||
|
{
|
||||||
|
string json;
|
||||||
|
while (_sendQueue.TryDequeue(out json))
|
||||||
|
_webSocket.Send(json);
|
||||||
|
await Task.Delay(_sendInterval, cancelToken).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (OperationCanceledException) { }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void QueueMessage(string message)
|
||||||
|
{
|
||||||
|
_sendQueue.Enqueue(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
@@ -28,7 +28,7 @@ namespace Discord.WebSockets
|
|||||||
|
|
||||||
Task Connect(string host, CancellationToken cancelToken);
|
Task Connect(string host, CancellationToken cancelToken);
|
||||||
Task Disconnect();
|
Task Disconnect();
|
||||||
void QueueMessage(byte[] message);
|
void QueueMessage(string message);
|
||||||
Task[] GetTasks(CancellationToken cancelToken);
|
Task[] GetTasks(CancellationToken cancelToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,7 +47,7 @@ namespace Discord.WebSockets
|
|||||||
private DateTime _lastHeartbeat;
|
private DateTime _lastHeartbeat;
|
||||||
private Task _runTask;
|
private Task _runTask;
|
||||||
|
|
||||||
public CancellationToken ParentCancelToken { get; set; }
|
public CancellationToken? ParentCancelToken { get; set; }
|
||||||
public CancellationToken CancelToken => _cancelToken;
|
public CancellationToken CancelToken => _cancelToken;
|
||||||
private CancellationTokenSource _cancelTokenSource;
|
private CancellationTokenSource _cancelTokenSource;
|
||||||
protected CancellationToken _cancelToken;
|
protected CancellationToken _cancelToken;
|
||||||
@@ -61,11 +61,16 @@ namespace Discord.WebSockets
|
|||||||
{
|
{
|
||||||
_client = client;
|
_client = client;
|
||||||
_logLevel = client.Config.LogLevel;
|
_logLevel = client.Config.LogLevel;
|
||||||
|
|
||||||
_loginTimeout = client.Config.ConnectionTimeout;
|
_loginTimeout = client.Config.ConnectionTimeout;
|
||||||
_cancelToken = new CancellationToken(true);
|
_cancelToken = new CancellationToken(true);
|
||||||
_connectedEvent = new ManualResetEventSlim(false);
|
_connectedEvent = new ManualResetEventSlim(false);
|
||||||
|
|
||||||
|
#if DNXCORE50
|
||||||
_engine = new BuiltInWebSocketEngine(client.Config.WebSocketInterval);
|
_engine = new BuiltInWebSocketEngine(client.Config.WebSocketInterval);
|
||||||
|
#else
|
||||||
|
_engine = new WSSharpWebSocketEngine(this, client.Config.UserAgent, client.Config.WebSocketInterval);
|
||||||
|
#endif
|
||||||
_engine.ProcessMessage += async (s, e) =>
|
_engine.ProcessMessage += async (s, e) =>
|
||||||
{
|
{
|
||||||
if (_logLevel >= LogMessageSeverity.Debug)
|
if (_logLevel >= LogMessageSeverity.Debug)
|
||||||
@@ -84,10 +89,11 @@ namespace Discord.WebSockets
|
|||||||
await Disconnect().ConfigureAwait(false);
|
await Disconnect().ConfigureAwait(false);
|
||||||
|
|
||||||
_cancelTokenSource = new CancellationTokenSource();
|
_cancelTokenSource = new CancellationTokenSource();
|
||||||
if (ParentCancelToken != null)
|
if (ParentCancelToken == null)
|
||||||
_cancelToken = CancellationTokenSource.CreateLinkedTokenSource(_cancelTokenSource.Token, ParentCancelToken).Token;
|
throw new InvalidOperationException("Parent cancel token was never set.");
|
||||||
else
|
_cancelToken = CancellationTokenSource.CreateLinkedTokenSource(_cancelTokenSource.Token, ParentCancelToken.Value).Token;
|
||||||
_cancelToken = _cancelTokenSource.Token;
|
/*else
|
||||||
|
_cancelToken = _cancelTokenSource.Token;*/
|
||||||
|
|
||||||
_lastHeartbeat = DateTime.UtcNow;
|
_lastHeartbeat = DateTime.UtcNow;
|
||||||
await _engine.Connect(Host, _cancelToken).ConfigureAwait(false);
|
await _engine.Connect(Host, _cancelToken).ConfigureAwait(false);
|
||||||
@@ -198,8 +204,7 @@ namespace Discord.WebSockets
|
|||||||
string json = JsonConvert.SerializeObject(message);
|
string json = JsonConvert.SerializeObject(message);
|
||||||
if (_logLevel >= LogMessageSeverity.Debug)
|
if (_logLevel >= LogMessageSeverity.Debug)
|
||||||
RaiseOnLog(LogMessageSeverity.Debug, $"Out: " + json);
|
RaiseOnLog(LogMessageSeverity.Debug, $"Out: " + json);
|
||||||
var bytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(message));
|
_engine.QueueMessage(json);
|
||||||
_engine.QueueMessage(bytes);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Task HeartbeatAsync(CancellationToken cancelToken)
|
private Task HeartbeatAsync(CancellationToken cancelToken)
|
||||||
|
|||||||
@@ -27,7 +27,8 @@
|
|||||||
"frameworks": {
|
"frameworks": {
|
||||||
"net45": {
|
"net45": {
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"RestSharp": "105.2.3"
|
"RestSharp": "105.2.3",
|
||||||
|
"WebSocketSharp": "1.0.3-rc9"
|
||||||
},
|
},
|
||||||
"frameworkAssemblies": {
|
"frameworkAssemblies": {
|
||||||
"System.Net.Http": "4.0.0.0"
|
"System.Net.Http": "4.0.0.0"
|
||||||
@@ -35,7 +36,8 @@
|
|||||||
},
|
},
|
||||||
"dnx451": {
|
"dnx451": {
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"RestSharp": "105.2.3"
|
"RestSharp": "105.2.3",
|
||||||
|
"WebSocketSharp": "1.0.3-rc9"
|
||||||
},
|
},
|
||||||
"frameworkAssemblies": {
|
"frameworkAssemblies": {
|
||||||
"System.Net.Http": "4.0.0.0"
|
"System.Net.Http": "4.0.0.0"
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||||
|
|||||||
Reference in New Issue
Block a user