Skip to content

Commit

Permalink
feat: new websocket transport (#156)
Browse files Browse the repository at this point in the history
* feat: new websocket transport

* Remove old websocket transport

* fix closing the conneciton when retrieving end point
  • Loading branch information
paulpach committed Apr 8, 2020
1 parent 9dcfc27 commit 23c7b0d
Show file tree
Hide file tree
Showing 14 changed files with 215 additions and 757 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public class AsyncTcpTransport : AsyncTransport
public override Task ListenAsync()
{
listener = TcpListener.Create(Port);
listener.Server.NoDelay = true;
listener.Start();
return Task.CompletedTask;
}
Expand Down
88 changes: 88 additions & 0 deletions Assets/Mirror/Runtime/Transport/Websocket/AsyncWsTransport.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Net.WebSockets;
using System.Threading.Tasks;
using Ninja.WebSockets;

namespace Mirror.Websocket
{
public class AsyncWsTransport : AsyncTransport
{
public int Port = 7778;

private TcpListener listener;
private readonly IWebSocketServerFactory webSocketServerFactory = new WebSocketServerFactory();

public override async Task<IConnection> AcceptAsync()
{
try
{
TcpClient tcpClient = await listener.AcceptTcpClientAsync();
var options = new WebSocketServerOptions { KeepAliveInterval = TimeSpan.FromSeconds(30), SubProtocol = "binary" };

Stream stream = tcpClient.GetStream();

WebSocketHttpContext context = await webSocketServerFactory.ReadHttpHeaderFromStreamAsync(tcpClient, stream);

WebSocket webSocket = await webSocketServerFactory.AcceptWebSocketAsync(context, options);
return new WebsocketConnection(webSocket);
}
catch (ObjectDisposedException)
{
// expected, the connection was closed
return null;
}
}

public override async Task<IConnection> ConnectAsync(Uri uri)
{
var options = new WebSocketClientOptions
{
NoDelay = true,
KeepAliveInterval = TimeSpan.Zero,
SecWebSocketProtocol = "binary"
};

if (uri.IsDefaultPort)
{
var builder = new UriBuilder(uri)
{
Port = Port
};
uri = builder.Uri;
}

var clientFactory = new WebSocketClientFactory();
WebSocket webSocket = await clientFactory.ConnectAsync(uri, options);

return new WebsocketConnection(webSocket);
}

public override void Disconnect()
{
listener.Stop();
}

public override Task ListenAsync()
{
listener = TcpListener.Create(Port);
listener.Server.NoDelay = true;
listener.Start();
return Task.CompletedTask;
}

public override Uri ServerUri()
{
var builder = new UriBuilder
{
Host = Dns.GetHostName(),
Port = this.Port,
Scheme = "ws"
};

return builder.Uri;
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

185 changes: 0 additions & 185 deletions Assets/Mirror/Runtime/Transport/Websocket/Client.cs

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,10 @@ public static void Write(WebSocketOpCode opCode, ArraySegment<byte> fromPayload,
// mask the payload
var maskKeyArraySegment = new ArraySegment<byte>(maskKey, 0, maskKey.Length);
WebSocketFrameCommon.ToggleMask(maskKeyArraySegment, fromPayload);
memoryStream.Write(fromPayload.Array, fromPayload.Offset, fromPayload.Count);
// unmask it so we don't destroy user's data
WebSocketFrameCommon.ToggleMask(maskKeyArraySegment, fromPayload);
return;
}

memoryStream.Write(fromPayload.Array, fromPayload.Offset, fromPayload.Count);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,6 @@ public class WebSocketImplementation : WebSocket

public event EventHandler<PongEventArgs> Pong;

public WebSocketHttpContext Context { get; set; }

internal WebSocketImplementation(Guid guid, Func<MemoryStream> recycledStreamFactory, Stream stream, TimeSpan keepAliveInterval, string secWebSocketExtensions, bool includeExceptionInCloseResponse, bool isClient, string subProtocol)
{
_guid = guid;
Expand Down Expand Up @@ -112,6 +110,7 @@ internal WebSocketImplementation(Guid guid, Func<MemoryStream> recycledStreamFac
public override string SubProtocol => _subProtocol;

public TimeSpan KeepAliveInterval { get; private set; }
public TcpClient TcpClient { get; internal set; }

/// <summary>
/// Receive web socket result
Expand Down Expand Up @@ -608,5 +607,11 @@ async Task CloseOutputAutoTimeoutAsync(WebSocketCloseStatus closeStatus, string
Events.Log.CloseOutputAutoTimeoutError(_guid, closeException.ToString(), closeStatus, statusDescription, ex.ToString());
}
}

// Closes the socket, no handshake
public void Close()
{
_stream.Close();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,10 @@ public async Task<WebSocket> ConnectAsync(Uri uri, WebSocketClientOptions option

token.ThrowIfCancellationRequested();
Stream stream = GetStream(guid, tcpClient, useSsl, host);
return await PerformHandshake(guid, uri, stream, options, token);
var websocket = await PerformHandshake(guid, uri, stream, options, token) as WebSocketImplementation;
websocket.TcpClient = tcpClient;

return websocket;
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,10 +101,11 @@ public async Task<WebSocket> AcceptWebSocketAsync(WebSocketHttpContext context,
await PerformHandshakeAsync(guid, context.HttpHeader, options.SubProtocol, context.Stream, token);
Events.Log.ServerHandshakeSuccess(guid);
string secWebSocketExtensions = null;
return new WebSocketImplementation(guid, _bufferFactory, context.Stream, options.KeepAliveInterval, secWebSocketExtensions, options.IncludeExceptionInCloseResponse, false, options.SubProtocol)
var websocket = new WebSocketImplementation(guid, _bufferFactory, context.Stream, options.KeepAliveInterval, secWebSocketExtensions, options.IncludeExceptionInCloseResponse, false, options.SubProtocol)
{
Context = context
TcpClient = context.Client
};
return websocket;
}

static void CheckWebSocketVersion(string httpHeader)
Expand Down

0 comments on commit 23c7b0d

Please sign in to comment.