Added support for compressed websocket messages.
This commit is contained in:
@@ -56,7 +56,11 @@ namespace Discord.API
|
||||
public int Version = 3;
|
||||
[JsonProperty("properties")]
|
||||
public Dictionary<string, string> Properties = new Dictionary<string, string>();
|
||||
}
|
||||
[JsonProperty("large_threshold", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public int? LargeThreshold;
|
||||
[JsonProperty("compress", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public bool? Compress;
|
||||
}
|
||||
}
|
||||
internal sealed class ResumeCommand : WebSocketMessage<ResumeCommand.Data>
|
||||
{
|
||||
|
||||
@@ -26,6 +26,8 @@ namespace Discord.Net.WebSockets
|
||||
LoginCommand msg = new LoginCommand();
|
||||
msg.Payload.Token = token;
|
||||
msg.Payload.Properties["$device"] = "Discord.Net";
|
||||
//msg.Payload.LargeThreshold = 50;
|
||||
msg.Payload.Compress = true;
|
||||
QueueMessage(msg);
|
||||
}
|
||||
private async Task Redirect(string server)
|
||||
@@ -67,6 +69,7 @@ namespace Discord.Net.WebSockets
|
||||
|
||||
protected override async Task ProcessMessage(string json)
|
||||
{
|
||||
await base.ProcessMessage(json);
|
||||
var msg = JsonConvert.DeserializeObject<WebSocketMessage>(json);
|
||||
if (msg.Sequence.HasValue)
|
||||
_lastSeq = msg.Sequence.Value;
|
||||
|
||||
@@ -5,15 +5,21 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace Discord.Net.WebSockets
|
||||
{
|
||||
internal class WebSocketMessageEventArgs : EventArgs
|
||||
internal class WebSocketBinaryMessageEventArgs : EventArgs
|
||||
{
|
||||
public readonly byte[] Data;
|
||||
public WebSocketBinaryMessageEventArgs(byte[] data) { Data = data; }
|
||||
}
|
||||
internal class WebSocketTextMessageEventArgs : EventArgs
|
||||
{
|
||||
public readonly string Message;
|
||||
public WebSocketMessageEventArgs(string msg) { Message = msg; }
|
||||
public WebSocketTextMessageEventArgs(string msg) { Message = msg; }
|
||||
}
|
||||
|
||||
internal interface IWebSocketEngine
|
||||
{
|
||||
event EventHandler<WebSocketMessageEventArgs> ProcessMessage;
|
||||
event EventHandler<WebSocketBinaryMessageEventArgs> BinaryMessage;
|
||||
event EventHandler<WebSocketTextMessageEventArgs> TextMessage;
|
||||
|
||||
Task Connect(string host, CancellationToken cancelToken);
|
||||
Task Disconnect();
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Linq;
|
||||
using System.Runtime.ExceptionServices;
|
||||
using System.Threading;
|
||||
@@ -51,13 +53,23 @@ namespace Discord.Net.WebSockets
|
||||
_connectedEvent = new ManualResetEventSlim(false);
|
||||
|
||||
_engine = new WebSocketSharpEngine(this, client.Config);
|
||||
_engine.ProcessMessage += async (s, e) =>
|
||||
_engine.BinaryMessage += async (s, e) =>
|
||||
{
|
||||
using (var compressed = new MemoryStream(e.Data, 2, e.Data.Length - 2))
|
||||
using (var decompressed = new MemoryStream())
|
||||
{
|
||||
using (var zlib = new DeflateStream(compressed, CompressionMode.Decompress))
|
||||
await zlib.CopyToAsync(decompressed);
|
||||
decompressed.Position = 0;
|
||||
using (var reader = new StreamReader(decompressed))
|
||||
await ProcessMessage(await reader.ReadToEndAsync());
|
||||
}
|
||||
};
|
||||
_engine.TextMessage += async (s, e) =>
|
||||
{
|
||||
if (_logLevel >= LogMessageSeverity.Debug)
|
||||
RaiseOnLog(LogMessageSeverity.Debug, $"In: {e.Message}");
|
||||
await ProcessMessage(e.Message);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
protected async Task BeginConnect()
|
||||
{
|
||||
@@ -185,7 +197,12 @@ namespace Discord.Net.WebSockets
|
||||
RaiseDisconnected(wasDisconnectUnexpected, _disconnectReason?.SourceException);
|
||||
}
|
||||
|
||||
protected abstract Task ProcessMessage(string json);
|
||||
protected virtual Task ProcessMessage(string json)
|
||||
{
|
||||
if (_logLevel >= LogMessageSeverity.Debug)
|
||||
RaiseOnLog(LogMessageSeverity.Debug, $"In: {json}");
|
||||
return TaskHelper.CompletedTask;
|
||||
}
|
||||
protected abstract object GetKeepAlive();
|
||||
|
||||
protected void QueueMessage(object message)
|
||||
|
||||
@@ -15,11 +15,17 @@ namespace Discord.Net.WebSockets
|
||||
private readonly WebSocket _parent;
|
||||
private WSSharpNWebSocket _webSocket;
|
||||
|
||||
public event EventHandler<WebSocketMessageEventArgs> ProcessMessage;
|
||||
private void RaiseProcessMessage(string msg)
|
||||
public event EventHandler<WebSocketBinaryMessageEventArgs> BinaryMessage;
|
||||
public event EventHandler<WebSocketTextMessageEventArgs> TextMessage;
|
||||
private void RaiseBinaryMessage(byte[] data)
|
||||
{
|
||||
if (ProcessMessage != null)
|
||||
ProcessMessage(this, new WebSocketMessageEventArgs(msg));
|
||||
if (BinaryMessage != null)
|
||||
BinaryMessage(this, new WebSocketBinaryMessageEventArgs(data));
|
||||
}
|
||||
private void RaiseTextMessage(string msg)
|
||||
{
|
||||
if (TextMessage != null)
|
||||
TextMessage(this, new WebSocketTextMessageEventArgs(msg));
|
||||
}
|
||||
|
||||
internal WebSocketSharpEngine(WebSocket parent, DiscordWSClientConfig config)
|
||||
@@ -34,9 +40,15 @@ namespace Discord.Net.WebSockets
|
||||
_webSocket = new WSSharpNWebSocket(host);
|
||||
_webSocket.EmitOnPing = false;
|
||||
_webSocket.EnableRedirection = true;
|
||||
_webSocket.Compression = WebSocketSharp.CompressionMethod.None;
|
||||
_webSocket.Compression = WebSocketSharp.CompressionMethod.Deflate;
|
||||
_webSocket.SetProxy(_config.ProxyUrl, _config.ProxyCredentials?.UserName, _config.ProxyCredentials?.Password);
|
||||
_webSocket.OnMessage += (s, e) => RaiseProcessMessage(e.Data);
|
||||
_webSocket.OnMessage += (s, e) =>
|
||||
{
|
||||
if (e.Type == WebSocketSharp.Opcode.Binary)
|
||||
RaiseBinaryMessage(e.RawData);
|
||||
else if (e.Type == WebSocketSharp.Opcode.Text)
|
||||
RaiseTextMessage(e.Data);
|
||||
};
|
||||
_webSocket.OnError += async (s, e) =>
|
||||
{
|
||||
_parent.RaiseOnLog(LogMessageSeverity.Error, e.Exception.GetBaseException().Message);
|
||||
|
||||
Reference in New Issue
Block a user