-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Commit
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
using System; | ||
using System.Net; | ||
using System.Net.Quic; | ||
using System.Net.Sockets; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using SuperSocket.Connection; | ||
|
||
#pragma warning disable CA2252 | ||
|
||
namespace SuperSocket.Quic.Connection | ||
{ | ||
public class QuicPipeConnection : StreamPipeConnection | ||
{ | ||
private readonly QuicPipeStream _stream; | ||
|
||
public QuicPipeConnection(QuicPipeStream stream, EndPoint remoteEndPoint, ConnectionOptions options) | ||
: this(stream, remoteEndPoint, null, options) | ||
{ | ||
_stream = stream; | ||
} | ||
|
||
public QuicPipeConnection(QuicPipeStream stream, EndPoint remoteEndPoint, EndPoint localEndPoint, | ||
ConnectionOptions options) | ||
: base(stream, remoteEndPoint, localEndPoint, options) | ||
{ | ||
_stream = stream; | ||
} | ||
|
||
protected override async Task StartInputPipeTask<TPackageInfo>(IObjectPipe<TPackageInfo> packagePipe, | ||
CancellationToken cancellationToken) | ||
{ | ||
await _stream.OpenStreamAsync(cancellationToken); | ||
await base.StartInputPipeTask(packagePipe, cancellationToken); | ||
} | ||
|
||
protected override bool IsIgnorableException(Exception e) | ||
{ | ||
if (base.IsIgnorableException(e)) | ||
return true; | ||
|
||
switch (e) | ||
{ | ||
case QuicException: | ||
case SocketException se when se.IsIgnorableSocketException(): | ||
return true; | ||
default: | ||
return false; | ||
} | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
using System; | ||
using System.IO; | ||
using System.Net.Quic; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
|
||
namespace SuperSocket.Quic.Connection; | ||
|
||
#pragma warning disable CA2252 | ||
|
||
public sealed class QuicPipeStream : Stream | ||
{ | ||
private Stream _stream; | ||
|
||
private readonly bool _serverStream; | ||
private readonly QuicConnection _connection; | ||
|
||
public QuicPipeStream(QuicConnection connection, bool serverStream) | ||
{ | ||
_connection = connection; | ||
_serverStream = serverStream; | ||
} | ||
|
||
public override bool CanRead => _stream.CanRead; | ||
public override bool CanSeek => _stream.CanSeek; | ||
public override bool CanWrite => _stream.CanWrite; | ||
public override long Length => _stream.Length; | ||
|
||
public override long Position | ||
{ | ||
get => _stream.Position; | ||
set => _stream.Position = value; | ||
} | ||
|
||
public async ValueTask OpenStreamAsync(CancellationToken cancellationToken) | ||
{ | ||
if (_serverStream) | ||
{ | ||
_stream = await _connection.AcceptInboundStreamAsync(cancellationToken); | ||
Check warning on line 39 in src/SuperSocket.Quic.Connection/QuicPipeStream.cs
|
||
} | ||
else | ||
{ | ||
_stream = await _connection.OpenOutboundStreamAsync(QuicStreamType.Bidirectional, cancellationToken); | ||
Check warning on line 43 in src/SuperSocket.Quic.Connection/QuicPipeStream.cs
|
||
} | ||
} | ||
|
||
public override void Flush() => _stream.Flush(); | ||
|
||
public override int Read(byte[] buffer, int offset, int count) => _stream.Read(buffer, offset, count); | ||
|
||
public override long Seek(long offset, SeekOrigin origin) => _stream.Seek(offset, origin); | ||
|
||
public override void SetLength(long value) => _stream.Flush(); | ||
|
||
public override void Close() => _stream.Close(); | ||
|
||
public override Task FlushAsync(CancellationToken cancellationToken) => _stream.FlushAsync(cancellationToken); | ||
|
||
public override Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) => | ||
_stream.ReadAsync(buffer, offset, count, cancellationToken); | ||
|
||
public override ValueTask<int> ReadAsync(Memory<byte> buffer, | ||
CancellationToken cancellationToken = default) => _stream.ReadAsync(buffer, cancellationToken); | ||
|
||
public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) => | ||
_stream.WriteAsync(buffer, offset, count, cancellationToken); | ||
|
||
public override ValueTask WriteAsync(ReadOnlyMemory<byte> buffer, | ||
CancellationToken cancellationToken = default) => | ||
_stream.WriteAsync(buffer, cancellationToken); | ||
|
||
public override void Write(ReadOnlySpan<byte> buffer) => _stream.Flush(); | ||
|
||
public override void Write(byte[] buffer, int offset, int count) => _stream.Flush(); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<Description>SuperSocket quic connection library.</Description> | ||
<TargetFrameworks>net7.0;net8.0</TargetFrameworks> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\SuperSocket.Connection\SuperSocket.Connection.csproj" /> | ||
</ItemGroup> | ||
|
||
</Project> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
using System.Collections.Generic; | ||
using System.IO; | ||
using System.Net.Quic; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using SuperSocket.Connection; | ||
using SuperSocket.Quic.Connection; | ||
using SuperSocket.Server.Abstractions; | ||
using SuperSocket.Server.Abstractions.Connections; | ||
|
||
#pragma warning disable CA2252 | ||
namespace SuperSocket.Quic | ||
{ | ||
internal class QuicConnectionFactory : IConnectionFactory | ||
{ | ||
private readonly ListenOptions _listenOptions; | ||
private readonly ConnectionOptions _connectionOptions; | ||
private readonly IEnumerable<IConnectionStreamInitializer> _connectionStreamInitializers; | ||
|
||
public QuicConnectionFactory( | ||
IConnectionStreamInitializersFactory connectionStreamInitializersFactory, | ||
ListenOptions listenOptions, | ||
ConnectionOptions connectionOptions) | ||
{ | ||
_listenOptions = listenOptions; | ||
_connectionOptions = connectionOptions; | ||
_connectionStreamInitializers = connectionStreamInitializersFactory.Create(_listenOptions); | ||
} | ||
|
||
public async Task<IConnection> CreateConnection(object connection, CancellationToken cancellationToken) | ||
{ | ||
Stream stream = null; | ||
var quicConnection = connection as QuicConnection; | ||
|
||
foreach (var initializer in _connectionStreamInitializers) | ||
{ | ||
stream = await initializer.InitializeAsync(quicConnection, cancellationToken); | ||
} | ||
|
||
var quicStream = (QuicPipeStream)stream; | ||
|
||
return new QuicPipeConnection(quicStream, quicConnection.RemoteEndPoint, | ||
Check warning on line 42 in src/SuperSocket.Quic/QuicConnectionFactory.cs
|
||
quicConnection.LocalEndPoint, _connectionOptions); | ||
Check warning on line 43 in src/SuperSocket.Quic/QuicConnectionFactory.cs
|
||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
using SuperSocket.Connection; | ||
using SuperSocket.Server.Abstractions; | ||
using SuperSocket.Server.Abstractions.Connections; | ||
|
||
namespace SuperSocket.Quic | ||
{ | ||
internal class QuicConnectionFactoryBuilder : IConnectionFactoryBuilder | ||
{ | ||
private readonly IConnectionStreamInitializersFactory _connectionStreamInitializersFactory; | ||
|
||
public QuicConnectionFactoryBuilder(IConnectionStreamInitializersFactory connectionStreamInitializersFactory) | ||
{ | ||
_connectionStreamInitializersFactory = connectionStreamInitializersFactory; | ||
} | ||
|
||
public IConnectionFactory Build(ListenOptions listenOptions, ConnectionOptions connectionOptions) | ||
{ | ||
return new QuicConnectionFactory(_connectionStreamInitializersFactory,listenOptions, connectionOptions); | ||
} | ||
} | ||
} |