| @@ -62,8 +62,8 @@ | |||||
| </Reference> | </Reference> | ||||
| <Reference Include="System" /> | <Reference Include="System" /> | ||||
| <Reference Include="System.Net.Http" /> | <Reference Include="System.Net.Http" /> | ||||
| <Reference Include="websocket-sharp, Version=1.0.2.59610, Culture=neutral, PublicKeyToken=5660b08a1845a91e, processorArchitecture=MSIL"> | |||||
| <HintPath>..\..\..\DiscordBot\packages\WebSocketSharp.1.0.3-rc10\lib\websocket-sharp.dll</HintPath> | |||||
| <Reference Include="WebSocket4Net, Version=0.14.1.0, Culture=neutral, PublicKeyToken=eb4e154b696bf72a, processorArchitecture=MSIL"> | |||||
| <HintPath>..\..\..\DiscordBot\packages\WebSocket4Net.0.14.1\lib\net45\WebSocket4Net.dll</HintPath> | |||||
| <Private>True</Private> | <Private>True</Private> | ||||
| </Reference> | </Reference> | ||||
| </ItemGroup> | </ItemGroup> | ||||
| @@ -239,6 +239,9 @@ | |||||
| <Compile Include="..\Discord.Net\Net\WebSockets\WebSocketSharpEngine.cs"> | <Compile Include="..\Discord.Net\Net\WebSockets\WebSocketSharpEngine.cs"> | ||||
| <Link>Net\WebSockets\WebSocketSharpEngine.cs</Link> | <Link>Net\WebSockets\WebSocketSharpEngine.cs</Link> | ||||
| </Compile> | </Compile> | ||||
| <Compile Include="..\Discord.Net\Net\WebSockets\WS4NetEngine.cs"> | |||||
| <Link>Net\WebSockets\WS4NetEngine.cs</Link> | |||||
| </Compile> | |||||
| <Compile Include="..\Discord.Net\Services\IService.cs"> | <Compile Include="..\Discord.Net\Services\IService.cs"> | ||||
| <Link>Services\IService.cs</Link> | <Link>Services\IService.cs</Link> | ||||
| </Compile> | </Compile> | ||||
| @@ -2,5 +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-rc10" targetFramework="net45" /> | |||||
| <package id="WebSocket4Net" version="0.14.1" targetFramework="net45" /> | |||||
| </packages> | </packages> | ||||
| @@ -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<string> _sendQueue; | |||||
| private readonly WebSocket _parent; | |||||
| private WS4NetWebSocket _webSocket; | |||||
| private ManualResetEventSlim _waitUntilConnect; | |||||
| public event EventHandler<WebSocketBinaryMessageEventArgs> BinaryMessage; | |||||
| public event EventHandler<WebSocketTextMessageEventArgs> 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<string>(); | |||||
| _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<Task> 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 | |||||
| @@ -75,7 +75,7 @@ namespace Discord.Net.WebSockets | |||||
| _connectedEvent = new ManualResetEventSlim(false); | _connectedEvent = new ManualResetEventSlim(false); | ||||
| #if !DOTNET5_4 | #if !DOTNET5_4 | ||||
| _engine = new WebSocketSharpEngine(this, _config, _logger); | |||||
| _engine = new WS4NetEngine(this, _config, _logger); | |||||
| #else | #else | ||||
| //_engine = new BuiltInWebSocketEngine(this, _config, _logger); | //_engine = new BuiltInWebSocketEngine(this, _config, _logger); | ||||
| #endif | #endif | ||||
| @@ -1,4 +1,4 @@ | |||||
| #if !DOTNET5_4 | |||||
| /*#if !DOTNET5_4 | |||||
| using System; | using System; | ||||
| using System.Collections.Concurrent; | using System.Collections.Concurrent; | ||||
| using System.Collections.Generic; | using System.Collections.Generic; | ||||
| @@ -42,7 +42,7 @@ namespace Discord.Net.WebSockets | |||||
| _webSocket = new WSSharpWebSocket(host); | _webSocket = new WSSharpWebSocket(host); | ||||
| _webSocket.EmitOnPing = false; | _webSocket.EmitOnPing = false; | ||||
| _webSocket.EnableRedirection = true; | _webSocket.EnableRedirection = true; | ||||
| _webSocket.Compression = WebSocketSharp.CompressionMethod.Deflate; | |||||
| //_webSocket.Compression = WebSocketSharp.CompressionMethod.Deflate; | |||||
| _webSocket.SetProxy(null, null, null); //Disable | _webSocket.SetProxy(null, null, null); //Disable | ||||
| //_webSocket.SetProxy(_config.ProxyUrl, _config.ProxyCredentials?.UserName, _config.ProxyCredentials?.Password); | //_webSocket.SetProxy(_config.ProxyUrl, _config.ProxyCredentials?.UserName, _config.ProxyCredentials?.Password); | ||||
| _webSocket.OnMessage += (s, e) => | _webSocket.OnMessage += (s, e) => | ||||
| @@ -115,4 +115,4 @@ namespace Discord.Net.WebSockets | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| #endif | |||||
| #endif*/ | |||||
| @@ -35,10 +35,10 @@ | |||||
| "frameworks": { | "frameworks": { | ||||
| "net45": { | "net45": { | ||||
| "dependencies": { | |||||
| "WebSocketSharp": "1.0.3-rc10", | |||||
| "RestSharp": "105.2.3" | |||||
| } | |||||
| "dependencies": { | |||||
| "WebSocket4Net": "0.14.1", | |||||
| "RestSharp": "105.2.3" | |||||
| } | |||||
| }, | }, | ||||
| "dotnet5.4": { | "dotnet5.4": { | ||||
| "dependencies": { | "dependencies": { | ||||