SignalR 能做什么?
- 服务器通过HTTP连接推送 数据到客户端
- 服务器与客户端RPC
- 易扩充
SignalR用什么技术传输数据?
- 用WebSockets,如果它是可靠的
- Otherwise, using other technologies, e.g. long polling
SignalR支持什么样的数据格式?
- 非压缩 JSON 文本或纯文本
- If you want to transfer compressed JSON or BSON or your binary data, you have to encode and decode the data (e.g. using Base64) or to implement
IJsonSerializer
by your own logic on the server side and implement the same logic on the client side. Note thatTextReader
andTextWriter
are used inside SignalR. That means you have to convert your data to text before transferring anyway.
开发包
All SignalR development packages can be fetched through NuGet. Normally, you just need to fetchMicrosoft.AspNet.SignalR
(Package ID) which contains most of the components you need, including:
Microsoft.AspNet.SignalR.Core
: 服务端组件 用于创建 SignalR 终结点.Microsoft.AspNet.SignalR.Owin
: OWIN host for SignalR.Microsoft.AspNet.SignalR.SystemWeb
: used to host SignalR in ASP.NET (via OWIN ASP.NET host).Microsoft.AspNet.SignalR.Js
: JavaScript client for SignalR.- Dependencies are also included: jQuery,
Newtonsoft.Json
,Microsoft.Owin.Host.SystemWeb
,Microsoft.Web.Infrastructure
and OWIN.
You could fetch other SignalR packages when you need:
Microsoft.AspNet.SignalR.Client
: .NET client for SignalR (includes WinRT, WP8 and Silverlight5).Microsoft.AspNet.SignalR.Redis
: Redis messaging backplane for scaling out SignalR in web farm.Microsoft.AspNet.SignalR.ServiceBus
: Windows Azure Service Bus messaging backplane for scaling out SignalR in web farm.Microsoft.AspNet.SignalR.SqlServer
: SQL Server messaging backplane for scaling out SignalR in web farm.Microsoft.AspNet.SignalR.Sample
: used to quickly setup a working sample in your application.
PersistentConnection
PersistentConnection 是
服务端提供 SignalR 服务的核心类 . Let me demonstrate how to use it.
First, I create a new ASP.NET web application and use NuGet to fetch the Microsoft.AspNet.SignalR
package. Then,定义一个从PersistentConnection继承的新类:
public class MyConnection : PersistentConnection
{
protected override Task OnConnected(IRequest request, string connectionId)
{
string msg = string.Format(
"A new user {0} has just joined. (ID: {1})",
request.QueryString["name"], connectionId);
return Connection.Broadcast(msg);
}
protected override Task OnReceived(IRequest request, string connectionId, string data)
{
// Broadcast data to all clients
string msg = string.Format(
"{0}: {1}", request.QueryString["name"], data);
return Connection.Broadcast(msg);
}
}
OnConnected
当客户端连接服务时触发. Connections are differentiated by connection IDs (GUID). The client can pass some information through IRequest.QueryString
when the connection is established. We can also get other HTTP items like cookies, posted form, headers and user principal fromIRequest
. Note all these items belong to the first request which requests to establish the connection.
OnReceived 当客户端数据到达时触发
. connectionId
tells which connection the data comes from. The data is in text format. You have to parse it by yourself if it does not represent plain text.
PersistentConnection.Connection
provides the 广播方法 to send a message to all connected clients; it also provides the Send
method to send a message to a specific connection or a group (using the group name as connectionId
). Both methods support an excluded list for connections that we don’t want to send messages to.
用MyConnection在Global.asax 文件的路由表注册
<span style="font-size:14px;">public class Global : System.Web.HttpApplication
{
protected void Application_Start(object sender, EventArgs e)
{
RouteTable.Routes.MapConnection<MyConnection>("echo", "/echo");
}
} </span>
write JavaScript in a web page to connect to our service:
<span style="font-size:14px;font-weight: normal;"><!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>SignalR Echo</title>
<script type="text/javascript" src="Scripts/jquery-2.0.3.min.js"></script>
<script type="text/javascript" src="Scripts/jquery.signalR-1.1.3.min.js"></script>
</head>
<body>
<script type="text/javascript">
function htmlEncode(value) {
return $("<div/>").text(value).html();
}
function addMsg(msg) {
$("#messages").append("<li>" + htmlEncode(msg) + "</li>");
}
$(function () {
$("#join").click(function () {
var connection = $.connection("/echo", "name=" + $("#name").val(), true);;
connection.received(function (data) {
addMsg(data);
});
connection.error(function (err) {
addMsg("Error: " + err);
});
addMsg("Connecting...");
connection.start(function () {
addMsg("Connected.");
$("#send").click(function () {
connection.send($("#msg").val());
});
});
});
});
</script>
<table>
<tr>
<td><span>Name:</span></td>
<td><input type="text" id="name" /></td>
<td><input type="button" value="Join" id="join" /></td>
</tr>
<tr>
<td><span>Message:</span></td>
<td><input type="text" id="msg" /></td>
<td><input type="button" value="Send" id="send" /></td>
</tr>
</table>
<ul id="messages"></ul>
</body>
</html> </span>
Next let’s create a .NET client. Just create a new console application and use NuGet to fetch theMicrosoft.AspNet.SignalR.Client
package. In Main
, I use the Connection class to communicate with our service:<span style="font-size:14px;font-weight: normal;">class Program
{
private const string ServiceUri = "http://localhost:12722/echo";
static void Main(string[] args)
{
var connection = new Connection(ServiceUri, "name=dzy");
connection.Received += connection_Received;
connection.StateChanged += connection_StateChanged;
Console.WriteLine("Connecting...");
connection.Start().Wait();
string inputMsg;
while (!string.IsNullOrEmpty(inputMsg = Console.ReadLine()))
{
connection.Send(inputMsg).Wait();
}
connection.Stop();
}
static void connection_StateChanged(StateChange state)
{
if (state.NewState == ConnectionState.Connected)
{
Console.WriteLine("Connected.");
}
}
static void connection_Received(string data)
{
Console.WriteLine(data);
}
} </span>