add more samples
This commit is contained in:
Родитель
d120ab8417
Коммит
a9d2c23f81
|
@ -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; }
|
||||
}
|
||||
}
|
Двоичные данные
Samples_2.1.0/WebApplication/Scripts/_references.js
Двоичные данные
Samples_2.1.0/WebApplication/Scripts/_references.js
Двоичный файл не отображается.
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
|
@ -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 () {
|
8
Samples_2.1.0/WebApplication/Scripts/jquery.signalR-2.1.0-pre-131116-b279.min.js
поставляемый
Normal file
8
Samples_2.1.0/WebApplication/Scripts/jquery.signalR-2.1.0-pre-131116-b279.min.js
поставляемый
Normal file
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
|
@ -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 »</a></p>
|
||||
</div>
|
||||
|
||||
<h4>New Features in SignalR 1.0.0</h4>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<h2>Hub<T></h2>
|
||||
<p>Derive class Hub<T> 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 »</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 »</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<T></a></h3>
|
||||
<p>Derive Hub<T> 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 »</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" />
|
||||
|
|
Загрузка…
Ссылка в новой задаче