Make things actually work (#10)
- Added build.cmd - Renamed the solution to match our conventions - Fixed bad doc comment references - Used strong name version of StackExchange.Redis
This commit is contained in:
parent
dfa9c927b7
commit
239999e4c9
|
|
@ -0,0 +1,32 @@
|
|||
language: csharp
|
||||
sudo: required
|
||||
dist: trusty
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- gettext
|
||||
- libcurl4-openssl-dev
|
||||
- libicu-dev
|
||||
- libssl-dev
|
||||
- libunwind8
|
||||
- zlib1g
|
||||
env:
|
||||
global:
|
||||
- DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
|
||||
- DOTNET_CLI_TELEMETRY_OPTOUT: 1
|
||||
mono:
|
||||
- 4.0.5
|
||||
os:
|
||||
- linux
|
||||
- osx
|
||||
osx_image: xcode7.1
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- release
|
||||
- dev
|
||||
- /^(.*\/)?ci-.*$/
|
||||
before_install:
|
||||
- if test "$TRAVIS_OS_NAME" == "osx"; then brew update; brew install openssl; ln -s /usr/local/opt/openssl/lib/libcrypto.1.0.0.dylib /usr/local/lib/; ln -s /usr/local/opt/openssl/lib/libssl.1.0.0.dylib /usr/local/lib/; fi
|
||||
script:
|
||||
- ./build.sh --quiet verify
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
init:
|
||||
- git config --global core.autocrlf true
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- release
|
||||
- dev
|
||||
- /^(.*\/)?ci-.*$/
|
||||
build_script:
|
||||
- build.cmd --quiet verify
|
||||
clone_depth: 1
|
||||
test: off
|
||||
deploy: off
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
@ECHO OFF
|
||||
PowerShell -NoProfile -NoLogo -ExecutionPolicy unrestricted -Command "[System.Threading.Thread]::CurrentThread.CurrentCulture = ''; [System.Threading.Thread]::CurrentThread.CurrentUICulture = '';& '%~dp0build.ps1' %*; exit $LASTEXITCODE"
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
$ErrorActionPreference = "Stop"
|
||||
|
||||
function DownloadWithRetry([string] $url, [string] $downloadLocation, [int] $retries)
|
||||
{
|
||||
while($true)
|
||||
{
|
||||
try
|
||||
{
|
||||
Invoke-WebRequest $url -OutFile $downloadLocation
|
||||
break
|
||||
}
|
||||
catch
|
||||
{
|
||||
$exceptionMessage = $_.Exception.Message
|
||||
Write-Host "Failed to download '$url': $exceptionMessage"
|
||||
if ($retries -gt 0) {
|
||||
$retries--
|
||||
Write-Host "Waiting 10 seconds before retrying. Retries left: $retries"
|
||||
Start-Sleep -Seconds 10
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
$exception = $_.Exception
|
||||
throw $exception
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cd $PSScriptRoot
|
||||
|
||||
$repoFolder = $PSScriptRoot
|
||||
$env:REPO_FOLDER = $repoFolder
|
||||
|
||||
$koreBuildZip="https://github.com/aspnet/KoreBuild/archive/dev.zip"
|
||||
if ($env:KOREBUILD_ZIP)
|
||||
{
|
||||
$koreBuildZip=$env:KOREBUILD_ZIP
|
||||
}
|
||||
|
||||
$buildFolder = ".build"
|
||||
$buildFile="$buildFolder\KoreBuild.ps1"
|
||||
|
||||
if (!(Test-Path $buildFolder)) {
|
||||
Write-Host "Downloading KoreBuild from $koreBuildZip"
|
||||
|
||||
$tempFolder=$env:TEMP + "\KoreBuild-" + [guid]::NewGuid()
|
||||
New-Item -Path "$tempFolder" -Type directory | Out-Null
|
||||
|
||||
$localZipFile="$tempFolder\korebuild.zip"
|
||||
|
||||
DownloadWithRetry -url $koreBuildZip -downloadLocation $localZipFile -retries 6
|
||||
|
||||
Add-Type -AssemblyName System.IO.Compression.FileSystem
|
||||
[System.IO.Compression.ZipFile]::ExtractToDirectory($localZipFile, $tempFolder)
|
||||
|
||||
New-Item -Path "$buildFolder" -Type directory | Out-Null
|
||||
copy-item "$tempFolder\**\build\*" $buildFolder -Recurse
|
||||
|
||||
# Cleanup
|
||||
if (Test-Path $tempFolder) {
|
||||
Remove-Item -Recurse -Force $tempFolder
|
||||
}
|
||||
}
|
||||
|
||||
&"$buildFile" $args
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
#!/usr/bin/env bash
|
||||
repoFolder="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
cd $repoFolder
|
||||
|
||||
koreBuildZip="https://github.com/aspnet/KoreBuild/archive/dev.zip"
|
||||
if [ ! -z $KOREBUILD_ZIP ]; then
|
||||
koreBuildZip=$KOREBUILD_ZIP
|
||||
fi
|
||||
|
||||
buildFolder=".build"
|
||||
buildFile="$buildFolder/KoreBuild.sh"
|
||||
|
||||
if test ! -d $buildFolder; then
|
||||
echo "Downloading KoreBuild from $koreBuildZip"
|
||||
|
||||
tempFolder="/tmp/KoreBuild-$(uuidgen)"
|
||||
mkdir $tempFolder
|
||||
|
||||
localZipFile="$tempFolder/korebuild.zip"
|
||||
|
||||
retries=6
|
||||
until (wget -O $localZipFile $koreBuildZip 2>/dev/null || curl -o $localZipFile --location $koreBuildZip 2>/dev/null)
|
||||
do
|
||||
echo "Failed to download '$koreBuildZip'"
|
||||
if [ "$retries" -le 0 ]; then
|
||||
exit 1
|
||||
fi
|
||||
retries=$((retries - 1))
|
||||
echo "Waiting 10 seconds before retrying. Retries left: $retries"
|
||||
sleep 10s
|
||||
done
|
||||
|
||||
unzip -q -d $tempFolder $localZipFile
|
||||
|
||||
mkdir $buildFolder
|
||||
cp -r $tempFolder/**/build/** $buildFolder
|
||||
|
||||
chmod +x $buildFile
|
||||
|
||||
# Cleanup
|
||||
if test ! -d $tempFolder; then
|
||||
rm -rf $tempFolder
|
||||
fi
|
||||
fi
|
||||
|
||||
$buildFile -r $repoFolder "$@"
|
||||
|
|
@ -26,7 +26,7 @@
|
|||
"target": "project"
|
||||
},
|
||||
"NETStandard.Library": "1.6.1-*",
|
||||
"StackExchange.Redis": "1.1.*"
|
||||
"StackExchange.Redis.StrongName": "1.1.605"
|
||||
},
|
||||
|
||||
"frameworks": {
|
||||
|
|
|
|||
|
|
@ -13,13 +13,13 @@ namespace Microsoft.Extensions.WebSockets.Internal
|
|||
/// <remarks>
|
||||
/// <para>
|
||||
/// Implementors of this type are generally considered thread-safe under the following condition: No two threads attempt to call either
|
||||
/// <see cref="ReceiveAsync"/> or <see cref="SendAsync"/> simultaneously. Different threads may call each method, but the same method
|
||||
/// <see cref="ExecuteAsync"/> or <see cref="SendAsync"/> simultaneously. Different threads may call each method, but the same method
|
||||
/// cannot be re-entered while it is being run in a different thread. However, ensure you verify that the specific implementor is
|
||||
/// thread-safe in this way. For example, <see cref="WebSocketConnection"/> (including the implementations returned by the
|
||||
/// static factory methods on that type) is thread-safe in this way.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// The general pattern of having a single thread running <see cref="ReceiveAsync"/> and a separate thread running <see cref="SendAsync"/> will
|
||||
/// The general pattern of having a single thread running <see cref="ExecuteAsync"/> and a separate thread running <see cref="SendAsync"/> will
|
||||
/// be thread-safe, as each method interacts with completely separate state.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
|
|
@ -70,56 +70,63 @@ namespace Microsoft.Extensions.WebSockets.Internal
|
|||
/// <summary>
|
||||
/// Sends the specified frame.
|
||||
/// </summary>
|
||||
/// <param name="connection">The <see cref="IWebSocketConnection"/></param>
|
||||
/// <param name="message">The message to send.</param>
|
||||
/// <returns>A <see cref="Task"/> that completes when the message has been written to the outbound stream.</returns>
|
||||
public static Task SendAsync(this IWebSocketConnection self, WebSocketFrame message) => self.SendAsync(message, CancellationToken.None);
|
||||
public static Task SendAsync(this IWebSocketConnection connection, WebSocketFrame message) => connection.SendAsync(message, CancellationToken.None);
|
||||
|
||||
/// <summary>
|
||||
/// Sends a Close frame to the other party. This does not guarantee that the client will send a responding close frame.
|
||||
/// </summary>
|
||||
/// <param name="connection">The <see cref="IWebSocketConnection"/></param>
|
||||
/// <param name="status">A <see cref="WebSocketCloseStatus"/> value to be sent to the client in the close frame</param>.
|
||||
/// <returns>A <see cref="Task"/> that completes when the close frame has been sent</returns>
|
||||
public static Task CloseAsync(this IWebSocketConnection self, WebSocketCloseStatus status) => self.CloseAsync(new WebSocketCloseResult(status), CancellationToken.None);
|
||||
public static Task CloseAsync(this IWebSocketConnection connection, WebSocketCloseStatus status) => connection.CloseAsync(new WebSocketCloseResult(status), CancellationToken.None);
|
||||
|
||||
/// <summary>
|
||||
/// Sends a Close frame to the other party. This does not guarantee that the client will send a responding close frame.
|
||||
/// </summary>
|
||||
/// <param name="connection">The <see cref="IWebSocketConnection"/></param>
|
||||
/// <param name="status">A <see cref="WebSocketCloseStatus"/> value to be sent to the client in the close frame</param>.
|
||||
/// <param name="description">A textual description of the reason for closing the connection.</param>
|
||||
/// <returns>A <see cref="Task"/> that completes when the close frame has been sent</returns>
|
||||
public static Task CloseAsync(this IWebSocketConnection self, WebSocketCloseStatus status, string description) => self.CloseAsync(new WebSocketCloseResult(status, description), CancellationToken.None);
|
||||
public static Task CloseAsync(this IWebSocketConnection connection, WebSocketCloseStatus status, string description) => connection.CloseAsync(new WebSocketCloseResult(status, description), CancellationToken.None);
|
||||
|
||||
/// <summary>
|
||||
/// Sends a Close frame to the other party. This does not guarantee that the client will send a responding close frame.
|
||||
/// </summary>
|
||||
/// <param name="connection">The <see cref="IWebSocketConnection"/></param>
|
||||
/// <param name="status">A <see cref="WebSocketCloseStatus"/> value to be sent to the client in the close frame</param>.
|
||||
/// <param name="cancellationToken">A <see cref="CancellationToken"/> that indicates when/if the send is cancelled.</param>
|
||||
/// <returns>A <see cref="Task"/> that completes when the close frame has been sent</returns>
|
||||
public static Task CloseAsync(this IWebSocketConnection self, WebSocketCloseStatus status, CancellationToken cancellationToken) => self.CloseAsync(new WebSocketCloseResult(status), cancellationToken);
|
||||
public static Task CloseAsync(this IWebSocketConnection connection, WebSocketCloseStatus status, CancellationToken cancellationToken) => connection.CloseAsync(new WebSocketCloseResult(status), cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Sends a Close frame to the other party. This does not guarantee that the client will send a responding close frame.
|
||||
/// </summary>
|
||||
/// <param name="connection">The <see cref="IWebSocketConnection"/></param>
|
||||
/// <param name="status">A <see cref="WebSocketCloseStatus"/> value to be sent to the client in the close frame</param>.
|
||||
/// <param name="description">A textual description of the reason for closing the connection.</param>
|
||||
/// <param name="cancellationToken">A <see cref="CancellationToken"/> that indicates when/if the send is cancelled.</param>
|
||||
/// <returns>A <see cref="Task"/> that completes when the close frame has been sent</returns>
|
||||
public static Task CloseAsync(this IWebSocketConnection self, WebSocketCloseStatus status, string description, CancellationToken cancellationToken) => self.CloseAsync(new WebSocketCloseResult(status, description), cancellationToken);
|
||||
public static Task CloseAsync(this IWebSocketConnection connection, WebSocketCloseStatus status, string description, CancellationToken cancellationToken) => connection.CloseAsync(new WebSocketCloseResult(status, description), cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Sends a Close frame to the other party. This does not guarantee that the client will send a responding close frame.
|
||||
/// </summary>
|
||||
/// <param name="connection">The <see cref="IWebSocketConnection"/></param>
|
||||
/// <param name="result">A <see cref="WebSocketCloseResult"/> with the payload for the close frame.</param>
|
||||
/// <returns>A <see cref="Task"/> that completes when the close frame has been sent</returns>
|
||||
public static Task CloseAsync(this IWebSocketConnection self, WebSocketCloseResult result) => self.CloseAsync(result, CancellationToken.None);
|
||||
public static Task CloseAsync(this IWebSocketConnection connection, WebSocketCloseResult result) => connection.CloseAsync(result, CancellationToken.None);
|
||||
|
||||
/// <summary>
|
||||
/// Runs the WebSocket receive loop, using the provided message handler.
|
||||
/// </summary>
|
||||
/// <param name="connection">The <see cref="IWebSocketConnection"/></param>
|
||||
/// <param name="messageHandler">The callback that will be invoked for each new frame</param>
|
||||
/// <returns>A <see cref="Task{WebSocketCloseResult}"/> that will complete when the client has sent a close frame, or the connection has been terminated</returns>
|
||||
public static Task<WebSocketCloseResult> ExecuteAsync(this IWebSocketConnection self, Action<WebSocketFrame> messageHandler) =>
|
||||
self.ExecuteAsync((frame, _) =>
|
||||
public static Task<WebSocketCloseResult> ExecuteAsync(this IWebSocketConnection connection, Action<WebSocketFrame> messageHandler) =>
|
||||
connection.ExecuteAsync((frame, _) =>
|
||||
{
|
||||
messageHandler(frame);
|
||||
return Task.CompletedTask;
|
||||
|
|
@ -128,10 +135,12 @@ namespace Microsoft.Extensions.WebSockets.Internal
|
|||
/// <summary>
|
||||
/// Runs the WebSocket receive loop, using the provided message handler.
|
||||
/// </summary>
|
||||
/// <param name="connection">The <see cref="IWebSocketConnection"/></param>
|
||||
/// <param name="messageHandler">The callback that will be invoked for each new frame</param>
|
||||
/// <param name="state">The state to pass to the callback when the delegate is invoked. This may be null.</param>
|
||||
/// <returns>A <see cref="Task{WebSocketCloseResult}"/> that will complete when the client has sent a close frame, or the connection has been terminated</returns>
|
||||
public static Task<WebSocketCloseResult> ExecuteAsync(this IWebSocketConnection self, Action<WebSocketFrame, object> messageHandler, object state) =>
|
||||
self.ExecuteAsync((frame, s) =>
|
||||
public static Task<WebSocketCloseResult> ExecuteAsync(this IWebSocketConnection connection, Action<WebSocketFrame, object> messageHandler, object state) =>
|
||||
connection.ExecuteAsync((frame, s) =>
|
||||
{
|
||||
messageHandler(frame, s);
|
||||
return Task.CompletedTask;
|
||||
|
|
@ -140,9 +149,10 @@ namespace Microsoft.Extensions.WebSockets.Internal
|
|||
/// <summary>
|
||||
/// Runs the WebSocket receive loop, using the provided message handler.
|
||||
/// </summary>
|
||||
/// <param name="connection">The <see cref="IWebSocketConnection"/></param>
|
||||
/// <param name="messageHandler">The callback that will be invoked for each new frame</param>
|
||||
/// <returns>A <see cref="Task{WebSocketCloseResult}"/> that will complete when the client has sent a close frame, or the connection has been terminated</returns>
|
||||
public static Task<WebSocketCloseResult> ExecuteAsync(this IWebSocketConnection self, Func<WebSocketFrame, Task> messageHandler) =>
|
||||
self.ExecuteAsync((frame, _) => messageHandler(frame), null);
|
||||
public static Task<WebSocketCloseResult> ExecuteAsync(this IWebSocketConnection connection, Func<WebSocketFrame, Task> messageHandler) =>
|
||||
connection.ExecuteAsync((frame, _) => messageHandler(frame), null);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,4 +12,4 @@ using System.Runtime.CompilerServices;
|
|||
[assembly: AssemblyProduct("Microsoft.Extensions.WebSockets")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
|
||||
[assembly: InternalsVisibleTo("Microsoft.Extensions.WebSockets.Tests")]
|
||||
[assembly: InternalsVisibleTo("Microsoft.Extensions.WebSockets.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
|
||||
|
|
|
|||
|
|
@ -18,11 +18,11 @@ namespace Microsoft.Extensions.WebSockets.Internal
|
|||
/// <remarks>
|
||||
/// <para>
|
||||
/// This type is thread-safe under the following condition: No two threads attempt to call either
|
||||
/// <see cref="ReceiveAsync"/> or <see cref="SendAsync"/> simultaneously. Different threads may call each method, but the same method
|
||||
/// <see cref="ExecuteAsync"/> or <see cref="SendAsync"/> simultaneously. Different threads may call each method, but the same method
|
||||
/// cannot be re-entered while it is being run in a different thread.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// The general pattern of having a single thread running <see cref="ReceiveAsync"/> and a separate thread running <see cref="SendAsync"/> will
|
||||
/// The general pattern of having a single thread running <see cref="ExecuteAsync"/> and a separate thread running <see cref="SendAsync"/> will
|
||||
/// be thread-safe, as each method interacts with completely separate state.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"version": "0.1.0-*",
|
||||
"description": "WebSockets client and server components.",
|
||||
"description": "Low-allocation Push-oriented WebSockets based on Channels",
|
||||
|
||||
"packOptions": {
|
||||
"repository": {
|
||||
|
|
@ -18,10 +18,10 @@
|
|||
"nowarn": [
|
||||
"CS1591"
|
||||
],
|
||||
"xmlDoc": true
|
||||
"xmlDoc": true,
|
||||
"allowUnsafe": true
|
||||
},
|
||||
|
||||
"description": "Low-allocation Push-oriented WebSockets based on Channels",
|
||||
"dependencies": {
|
||||
"Channels": "0.2.0-beta-*",
|
||||
"Channels.Text.Primitives": "0.2.0-beta-*",
|
||||
|
|
|
|||
Loading…
Reference in New Issue