Browse Source

Add basic websocket redirect support

tags/docs-0.9
Brandon Smith 9 years ago
parent
commit
43e54f0042
5 changed files with 58 additions and 9 deletions
  1. +15
    -2
      src/Discord.Net/API/Models/TextWebSocketCommands.cs
  2. +6
    -0
      src/Discord.Net/API/Models/TextWebSocketEvents.cs
  3. +32
    -3
      src/Discord.Net/DiscordDataSocket.cs
  4. +1
    -1
      src/Discord.Net/DiscordVoiceSocket.cs
  5. +4
    -3
      src/Discord.Net/DiscordWebSocket.cs

+ 15
- 2
src/Discord.Net/API/Models/TextWebSocketCommands.cs View File

@@ -15,9 +15,11 @@ namespace Discord.API.Models
{
[JsonProperty(PropertyName = "op")]
public int Operation;
[JsonProperty(PropertyName = "t")]
[JsonProperty(PropertyName = "t", NullValueHandling = NullValueHandling.Ignore)]
public string Type;
[JsonProperty(PropertyName = "d")]
[JsonProperty(PropertyName = "s", NullValueHandling = NullValueHandling.Ignore)]
public int? Sequence;
[JsonProperty(PropertyName = "d", NullValueHandling = NullValueHandling.Ignore)]
public object Payload;
}
internal abstract class WebSocketMessage<T> : WebSocketMessage
@@ -78,5 +80,16 @@ namespace Discord.API.Models
public string SelfDeaf;
}
}
public sealed class Resume : WebSocketMessage<Resume.Data>
{
public Resume() : base(6) { }
public class Data
{
[JsonProperty(PropertyName = "session_id")]
public string SessionId;
[JsonProperty(PropertyName = "seq")]
public int Sequence;
}
}
}
}

+ 6
- 0
src/Discord.Net/API/Models/TextWebSocketEvents.cs View File

@@ -36,6 +36,12 @@ namespace Discord.API.Models
public int HeartbeatInterval;
}

public sealed class Redirect
{
[JsonProperty(PropertyName = "url")]
public string Url;
}

//Servers
public sealed class GuildCreate : ExtendedServerInfo { }
public sealed class GuildUpdate : ServerInfo { }


+ 32
- 3
src/Discord.Net/DiscordDataSocket.cs View File

@@ -12,6 +12,8 @@ namespace Discord
internal sealed partial class DiscordDataSocket : DiscordWebSocket
{
private readonly ManualResetEventSlim _connectWaitOnLogin, _connectWaitOnLogin2;
private string _lastSession, _redirectServer;
private int _lastSeq;

public DiscordDataSocket(DiscordClient client, int timeout, int interval, bool isDebug)
: base(client, timeout, interval, isDebug)
@@ -20,10 +22,13 @@ namespace Discord
_connectWaitOnLogin2 = new ManualResetEventSlim(false);
}

public override Task ConnectAsync(string url)
public override async Task ConnectAsync(string url)
{
BeginConnect();
return base.ConnectAsync(url);
_lastSeq = 0;
_lastSession = null;
_redirectServer = null;
await BeginConnect();
await base.ConnectAsync(url);
}
public async Task Login(string token)
{
@@ -65,6 +70,8 @@ namespace Discord
protected override Task ProcessMessage(string json)
{
var msg = JsonConvert.DeserializeObject<WebSocketMessage>(json);
if (msg.Sequence.HasValue)
_lastSeq = msg.Sequence.Value;
switch (msg.Operation)
{
case 0:
@@ -72,6 +79,7 @@ namespace Discord
if (msg.Type == "READY")
{
var payload = (msg.Payload as JToken).ToObject<TextWebSocketEvents.Ready>();
_lastSession = payload.SessionId;
_heartbeatInterval = payload.HeartbeatInterval;
QueueMessage(new TextWebSocketCommands.UpdateStatus());
//QueueMessage(GetKeepAlive());
@@ -82,6 +90,15 @@ namespace Discord
_connectWaitOnLogin2.Set(); //Post-Event
}
break;
case 7:
{
var payload = (msg.Payload as JToken).ToObject<TextWebSocketEvents.Redirect>();
if (_isDebug)
RaiseOnDebugMessage(DebugMessageType.Connection, $"Redirected to {payload.Url}.");
_host = payload.Url;
DisconnectInternal(new Exception("Server is redirecting."), true);
}
break;
default:
if (_isDebug)
RaiseOnDebugMessage(DebugMessageType.WebSocketUnknownOpCode, "Unknown Opcode: " + msg.Operation);
@@ -107,5 +124,17 @@ namespace Discord
var joinVoice = new TextWebSocketCommands.JoinVoice();
QueueMessage(joinVoice);
}

protected override void OnConnect()
{
if (_redirectServer != null)
{
var resumeMsg = new TextWebSocketCommands.Resume();
resumeMsg.Payload.SessionId = _lastSession;
resumeMsg.Payload.Sequence = _lastSeq;
SendMessage(resumeMsg, _disconnectToken.Token);
}
_redirectServer = null;
}
}
}

+ 1
- 1
src/Discord.Net/DiscordVoiceSocket.cs View File

@@ -128,7 +128,7 @@ namespace Discord

public new async Task BeginConnect()
{
base.BeginConnect();
await base.BeginConnect();
var cancelToken = _disconnectToken.Token;

await Task.Yield();


+ 4
- 3
src/Discord.Net/DiscordWebSocket.cs View File

@@ -40,14 +40,15 @@ namespace Discord
_sendQueue = new ConcurrentQueue<byte[]>();
}

protected void BeginConnect()
protected virtual async Task BeginConnect()
{
await DisconnectAsync();
_disconnectToken = new CancellationTokenSource();
_disconnectReason = null;
}
public virtual async Task ConnectAsync(string url)
{
await DisconnectAsync();
//await DisconnectAsync();

var cancelToken = _disconnectToken.Token;

@@ -152,7 +153,7 @@ namespace Discord
try
{
result = await _webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), cancelToken);
}
}
catch (Win32Exception ex)
when (ex.HResult == HR_TIMEOUT)
{


Loading…
Cancel
Save