add HubException sample and console client samples

This commit is contained in:
Gustavo Armenta 2013-11-19 13:21:20 -08:00
Родитель fe1de49c93
Коммит 6289db74ce
25 изменённых файлов: 529 добавлений и 82 удалений

Просмотреть файл

@ -55,6 +55,8 @@
<Link>Features\HubT\ITaskScheduler.cs</Link>
</Compile>
<Compile Include="Features\HubT\HubTClient.cs" />
<Compile Include="Features\Hub\HubClient.cs" />
<Compile Include="Features\PersistentConnection\ConnectionClient.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>

Просмотреть файл

@ -0,0 +1,33 @@
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNet.SignalR.Client;
namespace ConsoleClient.Features.Hub
{
class HubClient
{
private TextWriter _traceWriter;
private IHubProxy _hubProxy;
public HubClient(TextWriter traceWriter)
{
_traceWriter = traceWriter;
}
public async Task RunAsync(string url)
{
var connection = new HubConnection(url);
connection.TraceWriter = _traceWriter;
_hubProxy = connection.CreateHubProxy("DemoHub");
_hubProxy.On<string>("hubMessage", (data) =>
{
_traceWriter.WriteLine("hubMessage: " + data);
});
await connection.Start();
await _hubProxy.Invoke("SendToMe", "Hello World!");
}
}
}

Просмотреть файл

@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNet.SignalR.Client;
namespace ConsoleClient.Features.PersistentConnection
{
class ConnectionClient
{
private TextWriter _traceWriter;
private Connection _connection;
public ConnectionClient(TextWriter traceWriter)
{
_traceWriter = traceWriter;
}
public async Task RunAsync(string url)
{
_connection = new Connection(url);
_connection.TraceWriter = _traceWriter;
_connection.Received += (data) =>
{
_traceWriter.WriteLine("received: " + data);
};
await _connection.Start();
await _connection.Send(new { Type = "sendToMe", Content = "Hello World!" });
}
}
}

Просмотреть файл

@ -1,5 +1,7 @@
using System;
using ConsoleClient.Features.Hub;
using ConsoleClient.Features.HubT;
using ConsoleClient.Features.PersistentConnection;
namespace ConsoleClient
{
@ -9,17 +11,11 @@ namespace ConsoleClient
{
Console.Write(
@"
New Features in SignalR 1.0.0
New Features in version 1.0.0
1. PersistentConnection
2. Hub
New Features in SignalR 1.0.1
New Features in SignalR 1.1.0
New Features in SignalR 1.1.1
New Features in SignalR 1.1.2
New Features in SignalR 1.1.3
New Features in SignalR 2.0.0
New Features in SignalR 2.1.0
1. Hub<T>
New Features in version 2.1.0
3. Hub<T>
Select sample you want to run: ");
var sample = Console.ReadKey().KeyChar;
@ -31,8 +27,16 @@ Select sample you want to run: ");
switch(sample)
{
case '1':
var client = new HubTClient(writer);
client.RunAsync(url).Wait();
var client = new ConnectionClient(writer);
client.RunAsync(url + "Connections/DemoPersistentConnection").Wait();
break;
case '2':
var hubClient = new HubClient(writer);
hubClient.RunAsync(url).Wait();
break;
case '3':
var hubTClient = new HubTClient(writer);
hubTClient.RunAsync(url).Wait();
break;
default:
break;

Просмотреть файл

@ -65,10 +65,21 @@ namespace WebApplication.Controllers
return View();
}
public ActionResult HubException()
{
return View();
}
[Authorize]
public ActionResult SendToUser()
{
return View();
}
[Authorize]
public ActionResult SendToUsers()
{
return View();
}
}
}

Просмотреть файл

@ -1,8 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Web;
using Microsoft.AspNet.SignalR;
namespace WebApplication.Features.SampleHub

Просмотреть файл

@ -0,0 +1,88 @@
using System;
using System.Threading.Tasks;
using Microsoft.AspNet.SignalR;
namespace WebApplication.Features.SampleHubException
{
public class DemoExceptionHub : Hub
{
public override Task OnConnected()
{
return Clients.All.hubMessage("OnConnected " + Context.ConnectionId);
}
public override Task OnDisconnected()
{
return Clients.All.hubMessage("OnDisconnected " + Context.ConnectionId);
}
public override Task OnReconnected()
{
return Clients.Caller.hubMessage("OnReconnected");
}
public void SendToMe(string value)
{
Clients.Caller.hubMessage(value);
}
public void SendToConnectionId(string connectionId, string value)
{
Clients.Client(connectionId).hubMessage(value);
}
public void SendToAll(string value)
{
Clients.All.hubMessage(value);
}
public void SendToGroup(string groupName, string value)
{
Clients.Group(groupName).hubMessage(value);
}
public void JoinGroup(string groupName, string connectionId)
{
if (string.IsNullOrEmpty(connectionId))
{
connectionId = Context.ConnectionId;
}
Groups.Add(connectionId, groupName);
Clients.All.hubMessage(connectionId + " joined group " + groupName);
}
public void LeaveGroup(string groupName, string connectionId)
{
if (string.IsNullOrEmpty(connectionId))
{
connectionId = Context.ConnectionId;
}
Groups.Remove(connectionId, groupName);
Clients.All.hubMessage(connectionId + " left group " + groupName);
}
public void IncrementClientVariable()
{
Clients.Caller.counter = Clients.Caller.counter + 1;
Clients.Caller.hubMessage("Incremented counter to " + Clients.Caller.counter);
}
public void ThrowOnVoidMethod()
{
throw new InvalidOperationException("ThrowOnVoidMethod");
}
public async Task ThrowOnTaskMethod()
{
await Task.Delay(TimeSpan.FromSeconds(1));
throw new InvalidOperationException("ThrowOnTaskMethod");
}
public void ThrowHubException()
{
throw new HubException("ThrowHubException", new { Detail = "I can provide additional error information here!" });
}
}
}

Просмотреть файл

@ -0,0 +1,162 @@
function writeError(line) {
var messages = $("#messages");
messages.append("<li style='color:red;'>" + getTimeString() + ' ' + line + "</li>");
}
function writeEvent(line) {
var messages = $("#messages");
messages.append("<li style='color:blue;'>" + getTimeString() + ' ' + line + "</li>");
}
function writeLine(line) {
var messages = $("#messages");
messages.append("<li style='color:black;'>" + getTimeString() + ' ' + line + "</li>");
}
function getTimeString() {
var currentTime = new Date();
return currentTime.toTimeString();
}
function printState(state) {
var messages = $("#Messages");
return ["connecting", "connected", "reconnecting", state, "disconnected"][state];
}
function getQueryVariable(variable) {
var query = window.location.search.substring(1),
vars = query.split("&"),
pair;
for (var i = 0; i < vars.length; i++) {
pair = vars[i].split("=");
if (pair[0] == variable) {
return unescape(pair[1]);
}
}
}
$(function () {
var connection = $.connection.hub,
hub = $.connection.demoExceptionHub;
connection.logging = true;
connection.connectionSlow(function () {
writeEvent("connectionSlow");
});
connection.disconnected(function () {
writeEvent("disconnected");
});
connection.error(function (error) {
writeError(error);
});
connection.reconnected(function () {
writeEvent("reconnected");
});
connection.reconnecting(function () {
writeEvent("reconnecting");
});
connection.starting(function () {
writeEvent("starting");
});
connection.stateChanged(function (state) {
writeEvent("stateChanged " + printState(state.oldState) + " => " + printState(state.newState));
var buttonIcon = $("#startStopIcon");
var buttonText = $("#startStopText");
if (printState(state.newState) == "connected") {
buttonIcon.removeClass("glyphicon glyphicon-play");
buttonIcon.addClass("glyphicon glyphicon-stop");
buttonText.text("Stop Connection");
} else if (printState(state.newState) == "disconnected") {
buttonIcon.removeClass("glyphicon glyphicon-stop");
buttonIcon.addClass("glyphicon glyphicon-play");
buttonText.text("Start Connection");
}
});
hub.client.hubMessage = function (data) {
writeLine("hubMessage: " + data);
}
$("#startStop").click(function () {
if (printState(connection.state) == "connected") {
connection.stop();
} else if (printState(connection.state) == "disconnected") {
var activeTransport = getQueryVariable("transport") || "auto";
connection.start({ transport: activeTransport })
.done(function () {
writeLine("connection started. Id=" + connection.id + ". Transport=" + connection.transport.name);
})
.fail(function (error) {
writeError(error);
});
}
});
$("#sendToMe").click(function () {
hub.server.sendToMe($("#message").val());
});
$("#sendToConnectionId").click(function () {
hub.server.sendToConnectionId($("#connectionId").val(), $("#message").val());
});
$("#sendBroadcast").click(function () {
hub.server.sendToAll($("#message").val());
});
$("#sendToGroup").click(function () {
hub.server.sendToGroup($("#groupName").val(), $("#message").val());
});
$("#joinGroup").click(function () {
hub.server.joinGroup($("#groupName").val(), $("#connectionId").val());
});
$("#leaveGroup").click(function () {
hub.server.leaveGroup($("#groupName").val(), $("#connectionId").val());
});
$("#clientVariable").click(function () {
if (!hub.state.counter) {
hub.state.counter = 0;
}
hub.server.incrementClientVariable();
});
$("#throwOnVoidMethod").click(function () {
hub.server.throwOnVoidMethod()
.done(function (value) {
writeLine(result);
})
.fail(function (error) {
writeError(error);
});
});
$("#throwOnTaskMethod").click(function () {
hub.server.throwOnTaskMethod()
.done(function (value) {
writeLine(result);
})
.fail(function (error) {
writeError(error);
});
});
$("#throwHubException").click(function () {
hub.server.throwHubException()
.done(function (value) {
writeLine(result);
})
.fail(function (error) {
writeError(error.message + "<pre>" + connection.json.stringify(error.data) + "</pre>");
});
});
});

Просмотреть файл

@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNet.SignalR;
using Newtonsoft.Json;

Просмотреть файл

@ -1,8 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Microsoft.AspNet.SignalR;
using Microsoft.AspNet.SignalR;
namespace WebApplication.Features.SendToUser
{
@ -17,10 +13,5 @@ namespace WebApplication.Features.SendToUser
{
Clients.User(userId).message(value);
}
public void SendToUsers(IList<string> userIds, string value)
{
Clients.Users(userIds).message(value);
}
}
}

Просмотреть файл

@ -17,9 +17,7 @@ $(function () {
var connection = $.connection.hub,
hub = $.connection.sendToUserHub,
message = $("#message"),
userId = $("#userId"),
userIdsMessage = $("#userIdsMessage"),
userIds = $("#userIds");
userId = $("#userId");
connection.logging = true;
@ -42,9 +40,4 @@ $(function () {
$("#sendToUser").click(function () {
hub.server.sendToUser(userId.val(), message.val());
});
$("#sendToUsers").click(function () {
var listUsers = userIds.val().split(";");
hub.server.sendToUsers(listUsers, userIdsMessage.val());
});
});

Просмотреть файл

@ -0,0 +1,13 @@
using System.Collections.Generic;
using Microsoft.AspNet.SignalR;
namespace WebApplication.Features.SendToUsers
{
public class SendToUsersHub : Hub
{
public void SendToUsers(IList<string> userIds, string value)
{
Clients.Users(userIds).message(value);
}
}
}

Просмотреть файл

@ -0,0 +1,40 @@
function writeError(line) {
var messages = $("#messages");
messages.append("<li style='color:red;'>" + getTimeString() + ' ' + line + "</li>");
}
function writeLine(line) {
var messages = $("#messages");
messages.append("<li style='color:black;'>" + getTimeString() + ' ' + line + "</li>");
}
function getTimeString() {
var currentTime = new Date();
return currentTime.toTimeString();
}
$(function () {
var connection = $.connection.hub,
hub = $.connection.sendToUsersHub,
message = $("#message"),
userIds = $("#userIds");
connection.logging = true;
hub.client.message = function (value) {
writeLine(value);
}
connection.start()
.done(function () {
writeLine("connected");
})
.fail(function (error) {
writeError(value);
});
$("#sendToUsers").click(function () {
var listUsers = userIds.val().split(";");
hub.server.sendToUsers(listUsers, message.val());
});
});

Двоичный файл не отображается.

Просмотреть файл

@ -3,8 +3,6 @@
Add security to your application, allow only authenticated users or specific user roles to access your SignalR endpoints.
</summary>
<br />
<h4>Instructions</h4>
<ol>
<li>Verify you are not logged in on this website, otherwise click "Log off" on the menu.</li>

Просмотреть файл

@ -3,8 +3,6 @@
Send Messages using a PersistentConnection or Hub from anywhere on the same process.
</summary>
<br />
<h4>Instructions</h4>
<ol>
<li>Click on start button.</li>
@ -12,7 +10,6 @@
<li>Click on stop button.</li>
</ol>
<br />
<div>
<h4>Form</h4>
<button id="startStop" class="btn"><i id="startStopIcon" class="glyphicon glyphicon-play" ></i> <span id="startStopText">Start</span></button>

Просмотреть файл

@ -3,8 +3,6 @@
Use HubConfiguration.EnableDetailedErrors to send full exception stack details from server to client.
</summary>
<br />
<h4>Instructions</h4>
<ol>
<li>Start connection.</li>
@ -13,7 +11,6 @@
<li>There is an error.data object available when the exception type is HubException.</li>
</ol>
<br />
<div>
<h4>Form</h4>
<br /><input type="text" id="message" placeholder="Message" size="100" />

Просмотреть файл

@ -3,15 +3,12 @@
Derive Hub class to use a high-level connection API to enable remote method invocation and typed messages.
</summary>
<br />
<h4>Instructions</h4>
<ol>
<li>Open multiple browser windows.</li>
<li>Use the form below to send messages to one or many users</li>
</ol>
<br />
<div>
<h4>Form</h4>
<br /><input type="text" id="message" placeholder="Message" size="100" />

Просмотреть файл

@ -0,0 +1,49 @@
<h2>HubException</h2>
<summary>
When throwing a HubException, you can add an arbitrary object to provide more error detail.
</summary>
<h4>Instructions</h4>
<ol>
<li>Start connection.</li>
<li>Click button "Throw on sync method"</li>
<li>Click button "Throw on async method"</li>
<li>Click button "Throw HubException"</li>
</ol>
<div>
<h4>Form</h4>
<br /><input type="text" id="message" placeholder="Message" size="100" />
<br /><input type="text" id="connectionId" placeholder="Connection Id" size="100" />
<br /><input type="text" id="groupName" placeholder="Group Name" size="100" />
<br />
<button id="startStop" class="btn"><i id="startStopIcon" class="glyphicon glyphicon-play"></i> <span id="startStopText">Start Connection</span></button>
<br />
Send:
<input type="button" id="sendToMe" class="btn" value="Send to me" />
<input type="button" id="sendToConnectionId" class="btn" value="Send to connectionId" />
<input type="button" id="sendBroadcast" class="btn" value="Send broadcast" />
<input type="button" id="sendToGroup" class="btn" value="Send to group" />
<br />
Client State Variables:
<input type="button" id="clientVariable" class="btn" value="Increment client variable" />
<br />
Group Management:
<input type="button" id="joinGroup" class="btn" value="Join Group" />
<input type="button" id="leaveGroup" class="btn" value="Leave Group" />
<br />
Exception Handling:
<input type="button" id="throwOnVoidMethod" class="btn" value="Throw on sync method" />
<input type="button" id="throwOnTaskMethod" class="btn" value="Throw on async method" />
<input type="button" id="throwHubException" class="btn" value="Throw HubException" />
</div>
<div>
<h4>Messages</h4>
<ul id="messages"></ul>
</div>
@section Scripts {
@Scripts.Render("~/signalr/js")
@Scripts.Render("~/Features/HubException/DemoExceptionHub.js")
}

Просмотреть файл

@ -3,8 +3,6 @@
Derive class Hub&lt;T&gt; where T is an interface containing methods on client-side to receive hub messages.
</summary>
<br />
<p>On server-side, implementing your Hub is easier as you get intellisense when sending messages to clients</p>
<img src="/Features/HubT/intellisense.jpg" />

Просмотреть файл

@ -3,15 +3,12 @@
Demonstrates all features of the lower-level connection API including starting and stopping, sending and receiving messages, and managing groups.
</summary>
<br />
<h4>Instructions</h4>
<ol>
<li>Open multiple browser windows.</li>
<li>Use the form below to send messages to one or many users</li>
</ol>
<br />
<div>
<h4>Form</h4>
<br /><input type="text" id="message" placeholder="Message" size="100" />

Просмотреть файл

@ -1,35 +1,23 @@
<h2>Send Message to authenticated user(s)</h2>
<h2>Send Message to an authenticated user</h2>
<summary>
Push messages to users logged in concurrently on multiple browser windows and devices by using their username.
</summary>
<br />
<h4>Instructions</h4>
<ol>
<li>Open multiple browsers (IE, Chrome, Firefox, etc), login with same user on some and a different user on the other windows.</li>
<li>Use the form below to send messages to one or many users</li>
</ol>
<br />
<div>
<h4>To a single user</h4>
<br /><input type="text" id="message" placeholder="Message" size="100" />
<input type="text" id="message" placeholder="Message" size="100" />
<br /><input type="text" id="userId" placeholder="User" size="100" />
<br />
<input type="button" id="sendToMe" class="btn" value="Send to me" />
<input type="button" id="sendToUser" class="btn" value="Send to specified userId" />
</div>
<br />
<div>
<h4>To multiple users</h4>
<br /><input type="text" id="userIdsMessage" placeholder="Message" size="100" />
<br /><input type="text" id="userIds" placeholder="Users (separate by semicolon)" size="100" />
<br />
<input type="button" id="sendToUsers" class="btn" value="Send to specified userIds" />
</div>
<div>
<h4>Received Messages</h4>
<ul id="messages"></ul>

Просмотреть файл

@ -0,0 +1,28 @@
<h2>Send Message to many authenticated users</h2>
<summary>
Push messages to users logged in concurrently on multiple browser windows and devices by using their username.
</summary>
<h4>Instructions</h4>
<ol>
<li>Open multiple browsers (IE, Chrome, Firefox, etc), login with same user on some and a different user on the other windows.</li>
<li>Use the form below to send messages to one or many users</li>
</ol>
<div>
<h4>To multiple users</h4>
<input type="text" id="message" placeholder="Message" size="100" />
<br /><input type="text" id="userIds" placeholder="Users (separate by semicolon)" size="100" />
<br />
<input type="button" id="sendToUsers" class="btn" value="Send to specified userIds" />
</div>
<div>
<h4>Received Messages</h4>
<ul id="messages"></ul>
</div>
@section Scripts {
@Scripts.Render("~/signalr/js")
@Scripts.Render("~/Features/SendToUsers/SendToUsersHub.js")
}

Просмотреть файл

@ -8,62 +8,87 @@
<p><a href="http://asp.net/signalr" class="btn btn-primary btn-large">Learn more &raquo;</a></p>
</div>
<h4>New Features in SignalR 1.0.0</h4>
<h3>New Features in version 1.0.0</h3>
<div class="row">
<div class="col-md-6">
<h3><a href="/Feature/PersistentConnection">PersistentConnection</a></h3>
<h4><a href="/Feature/PersistentConnection">PersistentConnection</a></h4>
<p>Derive PersistentConnection class to use a low-level connection API to send and receive untyped messages.</p>
</div>
<div class="col-md-6">
<h3><a href="/Feature/Hub">Hub</a></h3>
<h4><a href="/Feature/Hub">Hub</a></h4>
<p>Derive Hub class to use a high-level connection API to enable remote method invocation and typed messages.</p>
</div>
</div>
<div class="row">
<div class="col-md-6">
<h3><a href="/Feature/ConnectionManager">ConnectionManager</a></h3>
<h4><a href="/Feature/ConnectionManager">ConnectionManager</a></h4>
<p>Use GlobalHost.ConnectionManager to send Messages using a PersistentConnection or Hub from anywhere on the same process.</p>
</div>
<div class="col-md-6">
<h3><a href="/Feature/EnableDetailedErrors">EnableDetailedErrors</a></h3>
<h4><a href="/Feature/EnableDetailedErrors">EnableDetailedErrors</a></h4>
<p>Use HubConfiguration.EnableDetailedErrors to send full exception stack details from server to client.</p>
</div>
</div>
<div class="row">
<div class="col-md-6">
<h3><a href="/Feature/Authorization">Authorization</a></h3>
<h4><a href="/Feature/Authorization">Authorization</a></h4>
<p>Add security to your application, allow only authenticated users or specific user roles to access your SignalR endpoints.</p>
</div>
</div>
<h4>New Features in SignalR 1.1.0</h4>
<h3>New Features in version 1.1.0</h3>
<div class="row">
<div class="col-md-6">
<h3>Scaleout</h3>
<h4>Scaleout</h4>
<p>SignalR can run on multiple server instances using any of these technologies: Sql Server, Service Bus, Redis.</p>
</div>
<div class="col-md-6">
<h4>.NET Client improvements</h4>
<ul>
<li>Allow specifiying the JsonSerializer.</li>
<li>Allow specifiying request headers.</li>
<li>Allow specifiying client certificates.</li>
<li>Added tracing using Connection.TraceWriter property.</li>
</ul>
</div>
</div>
<h4>New Features in SignalR 1.1.1</h4>
<h4>New Features in SignalR 1.1.2</h4>
<h4>New Features in SignalR 1.1.3</h4>
<h4>New Features in SignalR 2.0.0</h4>
<h4>New Features in SignalR 2.1.0</h4>
<h3>New Features in version 2.0.0</h3>
<div class="row">
<div class="col-md-6">
<h3><a href="/Feature/HubT">Hub&lt;T&gt;</a></h3>
<h4>Portable Class Library</h4>
<p>Use a single SignalR client library on Windows Store, Windows Phone, and Silverlight applications.</p>
</div>
<div class="col-md-6">
<h4>Libraries for Xamarin</h4>
<p>Added client libraries for Android and iOS applications.</p>
</div>
</div>
<div class="row">
<div class="col-md-6">
<h4><a href="/Feature/SendToUser">Send to User</a></h4>
<p>Send messages to authenticated users by using their username instead of a connectionId.</p>
</div>
<div class="col-md-6">
<h4><a href="/Feature/HubException">HubException</a></h4>
<p>Send additional error data when there is an exception.</p>
</div>
</div>
<h3>New Features in version 2.1.0</h3>
<div class="row">
<div class="col-md-6">
<h4><a href="/Feature/HubT">Hub&lt;T&gt;</a></h4>
<p>Derive Hub&lt;T&gt; class where T is an interface containing client methods (methods you usually invoke in a C# client using hubProxy.On). The advantage is you get autocomplete on server side when typing Clients.Caller.</p>
</div>
<div class="col-md-6">
<h3><a href="/Feature/Progress">Progress</a></h3>
<h4><a href="/Feature/Progress">Progress</a></h4>
<p>Hub method taking a long time to complete its work, now it can easily return updates as the work is getting done.</p>
</div>
</div>
<div class="row">
<div class="col-md-6">
<h3><a href="/Feature/SendToUser">Send to User</a></h3>
<p>Send messages to authenticated users by using their username instead of a connectionId.</p>
<h4><a href="/Feature/SendToUsers">Send to Users</a></h4>
<p>Send messages to many authenticated users by using their usernames instead of a connectionIds.</p>
</div>
</div>

Просмотреть файл

@ -182,6 +182,7 @@
<Compile Include="Features\Authorization\AuthorizationPersistentConnection.cs" />
<Compile Include="Features\Authorization\Message.cs" />
<Compile Include="Features\ConnectionManager\BackgroundThread.cs" />
<Compile Include="Features\HubException\DemoExceptionHub.cs" />
<Compile Include="Features\HubT\ITaskAgent.cs" />
<Compile Include="Features\HubT\ITaskScheduler.cs" />
<Compile Include="Features\HubT\TaskSchedulerHub.cs" />
@ -189,6 +190,7 @@
<Compile Include="Features\PersistentConnection\DemoPersistentConnection.cs" />
<Compile Include="Features\PersistentConnection\Message.cs" />
<Compile Include="Features\Progress\LongRunningTaskHub.cs" />
<Compile Include="Features\SendToUsers\SendToUsersHub.cs" />
<Compile Include="Features\SendToUser\SendToUserHub.cs" />
<Compile Include="Global.asax.cs">
<DependentUpon>Global.asax</DependentUpon>
@ -206,10 +208,12 @@
<Content Include="Features\Authorization\AuthorizationPersistentConnection.js" />
<Content Include="Features\ConnectionManager\BackgroundThread.js" />
<Content Include="Features\EnableDetailedErrors\EnableDetailedErrors.js" />
<Content Include="Features\HubException\DemoExceptionHub.js" />
<Content Include="Features\HubT\intellisense.jpg" />
<Content Include="Features\Hub\DemoHub.js" />
<Content Include="Features\PersistentConnection\DemoPersistentConnection.js" />
<Content Include="Features\Progress\LongRunningTaskHub.js" />
<Content Include="Features\SendToUsers\SendToUsersHub.js" />
<Content Include="Features\SendToUser\SendToUserHub.js" />
<Content Include="fonts\glyphicons-halflings-regular.svg" />
<Content Include="Global.asax" />
@ -263,6 +267,8 @@
<Content Include="Views\Feature\Authorization.cshtml" />
<Content Include="Views\Feature\AuthorizationHub.cshtml" />
<Content Include="Views\Feature\AuthorizationPersistentConnection.cshtml" />
<Content Include="Views\Feature\SendToUsers.cshtml" />
<Content Include="Views\Feature\HubException.cshtml" />
</ItemGroup>
<ItemGroup>
<Folder Include="App_Data\" />