This commit is contained in:
unknown 2013-11-18 01:48:44 -08:00
Родитель d120ab8417
Коммит a9d2c23f81
24 изменённых файлов: 823 добавлений и 72 удалений

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

@ -32,8 +32,9 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.AspNet.SignalR.Client">
<HintPath>..\packages\Microsoft.AspNet.SignalR.Client.2.1.0-pre-131106-b269\lib\net45\Microsoft.AspNet.SignalR.Client.dll</HintPath>
<Reference Include="Microsoft.AspNet.SignalR.Client, Version=2.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Microsoft.AspNet.SignalR.Client.2.1.0-pre-131116-b279\lib\net45\Microsoft.AspNet.SignalR.Client.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=4.5.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.5.0.8\lib\net45\Newtonsoft.Json.dll</HintPath>

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

@ -9,7 +9,16 @@ namespace ConsoleClient
{
Console.Write(
@"
Samples SignalR 2.1.0
New Features in SignalR 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>
Select sample you want to run: ");

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

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.AspNet.SignalR.Client" version="2.1.0-pre-131106-b269" targetFramework="net45" />
<package id="Microsoft.AspNet.SignalR.Client" version="2.1.0-pre-131116-b279" targetFramework="net45" />
<package id="Newtonsoft.Json" version="5.0.8" targetFramework="net45" />
</packages>

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

@ -8,6 +8,21 @@ namespace WebApplication.Controllers
{
public class FeatureController : Controller
{
public ActionResult PersistentConnection()
{
return View();
}
public ActionResult Hub()
{
return View();
}
public ActionResult ConnectionManager()
{
return View();
}
public ActionResult HubT()
{
return View();

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

@ -0,0 +1,37 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Web;
using Microsoft.AspNet.SignalR;
using WebApplication.Features.SamplePersistentConnection;
namespace WebApplication.Features.SampleHub
{
public class BackgroundThread
{
public static bool Enabled { get; set; }
public static async Task SendOnPersistentConnection()
{
var context = GlobalHost.ConnectionManager.GetConnectionContext<DemoPersistentConnection>();
while (Enabled)
{
await context.Connection.Broadcast("BackgroundThread.SendOnPersistentConnection sending message on " + DateTime.Now.ToString("HH:mm:ss"));
await Task.Delay(TimeSpan.FromSeconds(2));
}
}
public static async Task SendOnHub()
{
var context = GlobalHost.ConnectionManager.GetHubContext<DemoHub>();
while (Enabled)
{
await context.Clients.All.hubMessage("BackgroundThread.SendOnHub sending message on " + DateTime.Now.ToString("HH:mm:ss"));
await Task.Delay(TimeSpan.FromSeconds(2));
}
}
}
}

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

@ -0,0 +1,94 @@
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("/Connections/DemoPersistentConnection"),
hubConnection = $.connection.hub,
hub = $.connection.demoHub;
connection.logging = true;
hubConnection.logging = true;
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");
} else if (printState(state.newState) == "disconnected") {
buttonIcon.removeClass("glyphicon glyphicon-stop");
buttonIcon.addClass("glyphicon glyphicon-play");
buttonText.text("Start");
}
});
connection.received(function (data) {
writeLine("received: " + data);
});
hub.client.hubMessage = function (data) {
writeLine("hubMessage: " + data);
}
$("#startStop").click(function () {
if (printState(connection.state) == "connected") {
hub.server.stopBackgroundThread();
connection.stop();
hubConnection.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);
});
hubConnection.start({ transport: activeTransport })
.done(function () {
writeLine("hubConnection started. Id=" + hubConnection.id + ". Transport=" + hubConnection.transport.name);
hub.server.startBackgroundThread();
})
.fail(function (error) {
writeError(error);
});
}
});
});

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

@ -0,0 +1,87 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Web;
using Microsoft.AspNet.SignalR;
namespace WebApplication.Features.SampleHub
{
public class DemoHub : 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)
{
Groups.Add(connectionId, groupName);
Clients.All.hubMessage(connectionId + " joined group " + groupName);
}
public void LeaveGroup(string groupName, string connectionId)
{
Groups.Remove(connectionId, groupName);
Clients.All.hubMessage(connectionId + " left group " + groupName);
}
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");
}
public void StartBackgroundThread()
{
BackgroundThread.Enabled = true;
BackgroundThread.SendOnPersistentConnection();
BackgroundThread.SendOnHub();
}
public void StopBackgroundThread()
{
BackgroundThread.Enabled = false;
}
}
}

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

@ -0,0 +1,155 @@
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.demoHub;
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());
});
$("#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);
});
});
});

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

@ -0,0 +1,60 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNet.SignalR;
using Newtonsoft.Json;
namespace WebApplication.Features.SamplePersistentConnection
{
public class DemoPersistentConnection : PersistentConnection
{
protected override Task OnConnected(IRequest request, string connectionId)
{
return Connection.Broadcast("OnConnected " + connectionId);
}
protected override Task OnDisconnected(IRequest request, string connectionId)
{
return Connection.Broadcast("OnDisconnected " + connectionId);
}
protected override Task OnReceived(IRequest request, string connectionId, string data)
{
var message = JsonConvert.DeserializeObject<Message>(data);
switch(message.Type)
{
case "sendToMe":
Connection.Send(connectionId, message.Content);
break;
case "sendToConnectionId":
Connection.Send(message.ConnectionId, message.Content);
break;
case "sendBroadcast":
Connection.Broadcast(message.Content);
break;
case "sendToGroup":
Groups.Send(message.GroupName, message.Content);
break;
case "joinGroup":
Groups.Add(message.ConnectionId, message.GroupName);
Connection.Broadcast(message.ConnectionId + " joined group " + message.GroupName);
break;
case "leaveGroup":
Groups.Remove(message.ConnectionId, message.GroupName);
Connection.Broadcast(message.ConnectionId + " left group " + message.GroupName);
break;
case "throw":
throw new InvalidOperationException("Client does not receive this error");
break;
}
return base.OnReceived(request, connectionId, data);
}
protected override Task OnReconnected(IRequest request, string connectionId)
{
return Connection.Send(connectionId, "OnReconnected");
}
}
}

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

@ -0,0 +1,128 @@
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("/Connections/DemoPersistentConnection");
connection.logging = true;
connection.connectionSlow(function () {
writeEvent("connectionSlow");
});
connection.disconnected(function () {
writeEvent("disconnected");
});
connection.error(function (error) {
writeError(error);
});
connection.received(function (data) {
writeLine("received " + connection.json.stringify(data));
});
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");
}
});
$("#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 () {
connection.send({ type: "sendToMe", content: $("#message").val() });
});
$("#sendToConnectionId").click(function () {
connection.send({ type: "sendToConnectionId", content: $("#message").val(), connectionId: $("#connectionId").val() });
});
$("#sendBroadcast").click(function () {
connection.send({ type: "sendBroadcast", content: $("#message").val() });
});
$("#sendToGroup").click(function () {
connection.send({ type: "sendToGroup", content: $("#message").val(), groupName: $("#groupName").val() });
});
$("#joinGroup").click(function () {
connection.send({ type: "joinGroup", groupName: $("#groupName").val(), connectionId: $("#connectionId").val() });
});
$("#leaveGroup").click(function () {
connection.send({ type: "leaveGroup", groupName: $("#groupName").val(), connectionId: $("#connectionId").val() });
});
$("#throw").click(function () {
connection.send({ type: "throw" });
});
});

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

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace WebApplication.Features.SamplePersistentConnection
{
public class Message
{
public string Type { get; set; }
public string ConnectionId { get; set; }
public string Content { get; set; }
public string GroupName { get; set; }
}
}

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

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

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

@ -364,11 +364,6 @@
against = against || window.location;
// If the url is protocol relative, prepend the current windows protocol to the url.
if (url.indexOf("//") === 0) {
url = against.protocol + url;
}
if (url.indexOf("http") !== 0) {
return false;
}
@ -492,6 +487,12 @@
config.transport = "longPolling";
}
// If the url is protocol relative, prepend the current windows protocol to the url.
if (connection.url.indexOf("//") === 0) {
connection.url = window.location.protocol + connection.url;
connection.log("Protocol relative URL detected, normalizing it to '" + connection.url + "'.");
}
if (this.isCrossDomain(connection.url)) {
connection.log("Auto detected cross domain url.");
@ -812,8 +813,10 @@
/// <param name="callback" type="Function">A callback function to execute when an error occurs on the connection</param>
/// <returns type="signalR" />
var connection = this;
$(connection).bind(events.onError, function (e, data) {
callback.call(connection, data);
$(connection).bind(events.onError, function (e, errorData, sendData) {
// In practice 'errorData' is the SignalR built error object.
// In practice 'sendData' is undefined for all error events except those triggered by ajaxSend. For ajaxSend 'sendData' is the original send payload.
callback.call(connection, errorData, sendData);
});
return connection;
},
@ -988,11 +991,12 @@
checkIfAlive(connection);
}
transportLogic.markActive(connection);
connection._.beatHandle = window.setTimeout(function () {
beat(connection);
}, connection._.beatInterval);
// Ensure that we successfully marked active before continuing the heartbeat.
if (transportLogic.markActive(connection)) {
connection._.beatHandle = window.setTimeout(function () {
beat(connection);
}, connection._.beatInterval);
}
}
function checkIfAlive(connection) {
@ -1375,7 +1379,7 @@
}
},
startHeartbeat: function(connection) {
startHeartbeat: function (connection) {
beat(connection);
},
@ -1383,8 +1387,13 @@
connection._.lastMessageAt = new Date().getTime();
},
markActive: function(connection) {
connection._.lastActiveAt = new Date().getTime();
markActive: function (connection) {
if (transportLogic.verifyLastActive(connection)) {
connection._.lastActiveAt = new Date().getTime();
return true;
}
return false;
},
ensureReconnectingState: function (connection) {
@ -1403,7 +1412,7 @@
}
},
verifyReconnect: function (connection) {
verifyLastActive: function (connection) {
if (new Date().getTime() - connection._.lastActiveAt >= connection.reconnectWindow) {
connection.log("There has not been an active server connection for an extended period of time. Stopping connection.");
connection.stop();
@ -1421,12 +1430,12 @@
// and a reconnectTimeout isn't already set.
if (isConnectedOrReconnecting(connection) && !connection._.reconnectTimeout) {
// Need to verify before the setTimeout occurs because an application sleep could occur during the setTimeout duration.
if (!transportLogic.verifyReconnect(connection)) {
if (!transportLogic.verifyLastActive(connection)) {
return;
}
connection._.reconnectTimeout = window.setTimeout(function () {
if (!transportLogic.verifyReconnect(connection)) {
if (!transportLogic.verifyLastActive(connection)) {
return;
}
@ -1908,13 +1917,13 @@
var that = this;
// Need to verify before the setTimeout occurs because an application sleep could occur during the setTimeout duration.
if (!transportLogic.verifyReconnect(connection)) {
if (!transportLogic.verifyLastActive(connection)) {
return;
}
window.setTimeout(function () {
// Verify that we're ok to reconnect.
if (!transportLogic.verifyReconnect(connection)) {
if (!transportLogic.verifyLastActive(connection)) {
return;
}
@ -2198,7 +2207,7 @@
// Therefore we don't want to change that failure code path.
if ((connection.state === signalR.connectionState.connected ||
connection.state === signalR.connectionState.reconnecting) &&
!transportLogic.verifyReconnect(connection)) {
!transportLogic.verifyLastActive(connection)) {
return;
}
@ -2578,7 +2587,7 @@
});
connection.error(function (errData, origData) {
var data, callbackId, callback;
var callbackId, callback;
if (connection.transport && connection.transport.name === "webSockets") {
// WebSockets connections have all callbacks removed on reconnect instead
@ -2591,26 +2600,18 @@
return;
}
try {
data = window.JSON.parse(origData);
if (!data.I) {
// The original data doesn't have a callback ID so not a send error
return;
}
} catch (e) {
// The original data is not a JSON payload so this is not a send error
return;
}
callbackId = data.I;
callbackId = origData.I;
callback = connection._.invocationCallbacks[callbackId];
// Invoke the callback with an error to reject the promise
callback.method.call(callback.scope, { E: errData });
// Verify that there is a callback bound (could have been cleared)
if (callback) {
// Delete the callback
connection._.invocationCallbacks[callbackId] = null;
delete connection._.invocationCallbacks[callbackId];
// Delete the callback
connection._.invocationCallbacks[callbackId] = null;
delete connection._.invocationCallbacks[callbackId];
// Invoke the callback with an error to reject the promise
callback.method.call(callback.scope, { E: errData });
}
});
connection.reconnecting(function () {

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

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

@ -1,5 +1,7 @@
using Microsoft.Owin;
using Microsoft.AspNet.SignalR;
using Microsoft.Owin;
using Owin;
using WebApplication.Features.SamplePersistentConnection;
[assembly: OwinStartupAttribute(typeof(WebApplication.Startup))]
namespace WebApplication
@ -10,6 +12,7 @@ namespace WebApplication
{
ConfigureAuth(app);
app.MapSignalR();
app.MapSignalR<DemoPersistentConnection>("/Connections/DemoPersistentConnection");
}
}
}

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

@ -0,0 +1,29 @@
<h2>ConnectionManager</h2>
<summary>
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>
<li>You should see incoming messages from a PersistentConnection and a Hub</li>
<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>
</div>
<div>
<h4>Messages</h4>
<ul id="messages"></ul>
</div>
@section Scripts {
@Scripts.Render("~/signalr/js")
@Scripts.Render("~/Features/ConnectionManager/BackgroundThread.js")
}

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

@ -0,0 +1,43 @@
<h2>Hub</h2>
<summary>
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" />
<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>
<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" />
<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/Hub/DemoHub.js")
}

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

@ -8,7 +8,7 @@
<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" />
<h4>Sample</h4>
<h4>Instructions</h4>
<p>
Run ConsoleClient to see a demo
</p>

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

@ -0,0 +1,39 @@
<h2>PersistentConnection</h2>
<summary>
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" />
<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>
<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" />
<input type="button" id="joinGroup" class="btn" value="Join Group" />
<input type="button" id="leaveGroup" class="btn" value="Leave Group" />
<input type="button" id="throw" class="btn" value="Throw Exception" />
</div>
<div>
<h4>Messages</h4>
<ul id="messages"></ul>
</div>
@section Scripts {
@Scripts.Render("~/signalr/js")
@Scripts.Render("~/Features/PersistentConnection/DemoPersistentConnection.js")
}

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

@ -5,7 +5,7 @@
<br />
<h4>Sample</h4>
<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>

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

@ -8,22 +8,45 @@
<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>
<div class="row">
<div class="col-md-6">
<h2>Hub&lt;T&gt;</h2>
<p>Derive class Hub&lt;T&gt; 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>
<p><a class="btn btn-default" href="/Feature/HubT">See Demo &raquo;</a></p>
<h3><a href="/Feature/PersistentConnection">PersistentConnection</a></h3>
<p>Derive PersistentConnection class to use a low-level connection API to send and receive untyped messages.</p>
</div>
<div class="col-md-6">
<h2>Progress</h2>
<p>Hub method taking a long time to complete its work, now it can easily return updates as the work is getting done.</p>
<p><a class="btn btn-default" href="/Feature/Progress">See Demo &raquo;</a></p>
<h3><a href="/Feature/Hub">Hub</a></h3>
<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">
<h2>Send to User</h2>
<h3><a href="/Feature/ConnectionManager">ConnectionManager</a></h3>
<p>Use GlobalHost.ConnectionManager to send Messages using a PersistentConnection or Hub from anywhere on the same process.</p>
</div>
</div>
<h4>New Features in SignalR 1.0.1</h4>
<h4>New Features in SignalR 1.1.0</h4>
<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>
<div class="row">
<div class="col-md-6">
<h3><a href="/Feature/HubT">Hub&lt;T&gt;</a></h3>
<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>
<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>
<p><a class="btn btn-default" href="/Feature/SendToUser">See Demo &raquo;</a></p>
</div>
</div>

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

@ -39,11 +39,13 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.AspNet.SignalR.Core">
<HintPath>..\packages\Microsoft.AspNet.SignalR.Core.2.1.0-pre-131106-b269\lib\net45\Microsoft.AspNet.SignalR.Core.dll</HintPath>
<Reference Include="Microsoft.AspNet.SignalR.Core, Version=2.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Microsoft.AspNet.SignalR.Core.2.1.0-pre-131116-b279\lib\net45\Microsoft.AspNet.SignalR.Core.dll</HintPath>
</Reference>
<Reference Include="Microsoft.AspNet.SignalR.SystemWeb">
<HintPath>..\packages\Microsoft.AspNet.SignalR.SystemWeb.2.1.0-pre-131106-b269\lib\net45\Microsoft.AspNet.SignalR.SystemWeb.dll</HintPath>
<Reference Include="Microsoft.AspNet.SignalR.SystemWeb, Version=2.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Microsoft.AspNet.SignalR.SystemWeb.2.1.0-pre-131116-b279\lib\net45\Microsoft.AspNet.SignalR.SystemWeb.dll</HintPath>
</Reference>
<Reference Include="Microsoft.CSharp" />
<Reference Include="Microsoft.Owin, Version=2.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
@ -176,9 +178,13 @@
<Compile Include="Controllers\AccountController.cs" />
<Compile Include="Controllers\FeatureController.cs" />
<Compile Include="Controllers\HomeController.cs" />
<Compile Include="Features\ConnectionManager\BackgroundThread.cs" />
<Compile Include="Features\HubT\ITaskAgent.cs" />
<Compile Include="Features\HubT\ITaskScheduler.cs" />
<Compile Include="Features\HubT\TaskSchedulerHub.cs" />
<Compile Include="Features\Hub\DemoHub.cs" />
<Compile Include="Features\PersistentConnection\DemoPersistentConnection.cs" />
<Compile Include="Features\PersistentConnection\Message.cs" />
<Compile Include="Features\Progress\LongRunningTaskHub.cs" />
<Compile Include="Features\SendToUser\SendToUserHub.cs" />
<Compile Include="Global.asax.cs">
@ -193,7 +199,10 @@
<Content Include="Content\bootstrap.css" />
<Content Include="Content\bootstrap.min.css" />
<Content Include="favicon.ico" />
<Content Include="Features\ConnectionManager\BackgroundThread.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\SendToUser\SendToUserHub.js" />
<Content Include="fonts\glyphicons-halflings-regular.svg" />
@ -205,8 +214,8 @@
<Content Include="Scripts\jquery-1.10.2.js" />
<Content Include="Scripts\jquery-1.10.2.min.js" />
<None Include="Scripts\jquery.validate-vsdoc.js" />
<Content Include="Scripts\jquery.signalR-2.1.0-pre-131106-b269.js" />
<Content Include="Scripts\jquery.signalR-2.1.0-pre-131106-b269.min.js" />
<Content Include="Scripts\jquery.signalR-2.1.0-pre-131116-b279.js" />
<Content Include="Scripts\jquery.signalR-2.1.0-pre-131116-b279.min.js" />
<Content Include="Scripts\jquery.validate.js" />
<Content Include="Scripts\jquery.validate.min.js" />
<Content Include="Scripts\jquery.validate.unobtrusive.js" />
@ -241,6 +250,9 @@
<Content Include="Views\Feature\Progress.cshtml" />
<Content Include="Views\Feature\HubT.cshtml" />
<Content Include="Views\Feature\SendToUser.cshtml" />
<Content Include="Views\Feature\PersistentConnection.cshtml" />
<Content Include="Views\Feature\Hub.cshtml" />
<Content Include="Views\Feature\ConnectionManager.cshtml" />
</ItemGroup>
<ItemGroup>
<Folder Include="App_Data\" />

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

@ -10,10 +10,10 @@
<package id="Microsoft.AspNet.Identity.Owin" version="1.0.0" targetFramework="net45" />
<package id="Microsoft.AspNet.Mvc" version="5.0.0" targetFramework="net45" />
<package id="Microsoft.AspNet.Razor" version="3.0.0" targetFramework="net45" />
<package id="Microsoft.AspNet.SignalR" version="2.1.0-pre-131106-b269" targetFramework="net45" />
<package id="Microsoft.AspNet.SignalR.Core" version="2.1.0-pre-131106-b269" targetFramework="net45" />
<package id="Microsoft.AspNet.SignalR.JS" version="2.1.0-pre-131106-b269" targetFramework="net45" />
<package id="Microsoft.AspNet.SignalR.SystemWeb" version="2.1.0-pre-131106-b269" targetFramework="net45" />
<package id="Microsoft.AspNet.SignalR" version="2.1.0-pre-131116-b279" targetFramework="net45" />
<package id="Microsoft.AspNet.SignalR.Core" version="2.1.0-pre-131116-b279" targetFramework="net45" />
<package id="Microsoft.AspNet.SignalR.JS" version="2.1.0-pre-131116-b279" targetFramework="net45" />
<package id="Microsoft.AspNet.SignalR.SystemWeb" version="2.1.0-pre-131116-b279" targetFramework="net45" />
<package id="Microsoft.AspNet.Web.Optimization" version="1.1.1" targetFramework="net45" />
<package id="Microsoft.AspNet.WebPages" version="3.0.0" targetFramework="net45" />
<package id="Microsoft.jQuery.Unobtrusive.Validation" version="3.0.0" targetFramework="net45" />