diff --git a/src/Discord.Net.Net45/Discord.Net.csproj b/src/Discord.Net.Net45/Discord.Net.csproj index 61f89a7a4..dbfbb84d8 100644 --- a/src/Discord.Net.Net45/Discord.Net.csproj +++ b/src/Discord.Net.Net45/Discord.Net.csproj @@ -62,8 +62,8 @@ - - ..\..\..\DiscordBot\packages\WebSocketSharp.1.0.3-rc10\lib\websocket-sharp.dll + + ..\..\..\DiscordBot\packages\WebSocket4Net.0.14.1\lib\net45\WebSocket4Net.dll True @@ -239,6 +239,9 @@ Net\WebSockets\WebSocketSharpEngine.cs + + Net\WebSockets\WS4NetEngine.cs + Services\IService.cs diff --git a/src/Discord.Net.Net45/packages.config b/src/Discord.Net.Net45/packages.config index ca992a939..b267bb536 100644 --- a/src/Discord.Net.Net45/packages.config +++ b/src/Discord.Net.Net45/packages.config @@ -2,5 +2,5 @@ - + \ No newline at end of file diff --git a/src/Discord.Net/Net/WebSockets/WS4NetEngine.cs b/src/Discord.Net/Net/WebSockets/WS4NetEngine.cs new file mode 100644 index 000000000..bdcbd423c --- /dev/null +++ b/src/Discord.Net/Net/WebSockets/WS4NetEngine.cs @@ -0,0 +1,128 @@ +#if !DOTNET5_4 +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using WS4NetWebSocket = WebSocket4Net.WebSocket; + +namespace Discord.Net.WebSockets +{ + internal class WS4NetEngine : IWebSocketEngine + { + private readonly DiscordConfig _config; + private readonly Logger _logger; + private readonly ConcurrentQueue _sendQueue; + private readonly WebSocket _parent; + private WS4NetWebSocket _webSocket; + private ManualResetEventSlim _waitUntilConnect; + + public event EventHandler BinaryMessage; + public event EventHandler TextMessage; + private void RaiseBinaryMessage(byte[] data) + { + if (BinaryMessage != null) + BinaryMessage(this, new WebSocketBinaryMessageEventArgs(data)); + } + private void RaiseTextMessage(string msg) + { + if (TextMessage != null) + TextMessage(this, new WebSocketTextMessageEventArgs(msg)); + } + + internal WS4NetEngine(WebSocket parent, DiscordConfig config, Logger logger) + { + _parent = parent; + _config = config; + _logger = logger; + _sendQueue = new ConcurrentQueue(); + _waitUntilConnect = new ManualResetEventSlim(); + } + + public Task Connect(string host, CancellationToken cancelToken) + { + _webSocket = new WS4NetWebSocket(host); + _webSocket.EnableAutoSendPing = false; + _webSocket.NoDelay = true; + _webSocket.Proxy = null; //Disable + + _webSocket.DataReceived += (s, e) => + { + RaiseBinaryMessage(e.Data); + }; + _webSocket.MessageReceived += (s, e) => + { + RaiseTextMessage(e.Message); + }; + _webSocket.Error += async (s, e) => + { + _logger.Log(LogSeverity.Error, "WebSocket Error", e.Exception); + await _parent.SignalDisconnect(e.Exception, isUnexpected: true).ConfigureAwait(false); + _waitUntilConnect.Set(); + }; + _webSocket.Closed += async (s, e) => + { + /*string code = e.WasClean ? e.Code.ToString() : "Unexpected"; + string reason = e.Reason != "" ? e.Reason : "No Reason";*/ + var ex = new Exception($"Got Close Message");// ({code}): {reason}"); + await _parent.SignalDisconnect(ex, isUnexpected: false/*true*/).ConfigureAwait(false); + _waitUntilConnect.Set(); + }; + _webSocket.Opened += (s, e) => + { + _waitUntilConnect.Set(); + }; + + _waitUntilConnect.Reset(); + _webSocket.Open(); + _waitUntilConnect.Wait(cancelToken); + return TaskHelper.CompletedTask; + } + + public Task Disconnect() + { + string ignored; + while (_sendQueue.TryDequeue(out ignored)) { } + + var socket = _webSocket; + _webSocket = null; + if (socket != null) + socket.Close(); + + return TaskHelper.CompletedTask; + } + + public IEnumerable GetTasks(CancellationToken cancelToken) + { + return new Task[] + { + SendAsync(cancelToken) + }; + } + + private Task SendAsync(CancellationToken cancelToken) + { + var sendInterval = _config.WebSocketInterval; + return Task.Run(async () => + { + try + { + while (!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 \ No newline at end of file diff --git a/src/Discord.Net/Net/WebSockets/WebSocket.cs b/src/Discord.Net/Net/WebSockets/WebSocket.cs index ea76037b2..38bb8fd72 100644 --- a/src/Discord.Net/Net/WebSockets/WebSocket.cs +++ b/src/Discord.Net/Net/WebSockets/WebSocket.cs @@ -75,7 +75,7 @@ namespace Discord.Net.WebSockets _connectedEvent = new ManualResetEventSlim(false); #if !DOTNET5_4 - _engine = new WebSocketSharpEngine(this, _config, _logger); + _engine = new WS4NetEngine(this, _config, _logger); #else //_engine = new BuiltInWebSocketEngine(this, _config, _logger); #endif diff --git a/src/Discord.Net/Net/WebSockets/WebSocketSharpEngine.cs b/src/Discord.Net/Net/WebSockets/WebSocketSharpEngine.cs index e4933cec6..7c99c5fe3 100644 --- a/src/Discord.Net/Net/WebSockets/WebSocketSharpEngine.cs +++ b/src/Discord.Net/Net/WebSockets/WebSocketSharpEngine.cs @@ -1,4 +1,4 @@ -#if !DOTNET5_4 +/*#if !DOTNET5_4 using System; using System.Collections.Concurrent; using System.Collections.Generic; @@ -42,7 +42,7 @@ namespace Discord.Net.WebSockets _webSocket = new WSSharpWebSocket(host); _webSocket.EmitOnPing = false; _webSocket.EnableRedirection = true; - _webSocket.Compression = WebSocketSharp.CompressionMethod.Deflate; + //_webSocket.Compression = WebSocketSharp.CompressionMethod.Deflate; _webSocket.SetProxy(null, null, null); //Disable //_webSocket.SetProxy(_config.ProxyUrl, _config.ProxyCredentials?.UserName, _config.ProxyCredentials?.Password); _webSocket.OnMessage += (s, e) => @@ -115,4 +115,4 @@ namespace Discord.Net.WebSockets } } } -#endif \ No newline at end of file +#endif*/ \ No newline at end of file diff --git a/src/Discord.Net/project.json b/src/Discord.Net/project.json index b0d08bf04..8be5cb8c9 100644 --- a/src/Discord.Net/project.json +++ b/src/Discord.Net/project.json @@ -35,10 +35,10 @@ "frameworks": { "net45": { - "dependencies": { - "WebSocketSharp": "1.0.3-rc10", - "RestSharp": "105.2.3" - } + "dependencies": { + "WebSocket4Net": "0.14.1", + "RestSharp": "105.2.3" + } }, "dotnet5.4": { "dependencies": {