## 8.2 ABP实时服务 - 集成SignalR
### 8.2.1 简介
在基于ABP创建的项目中,有一个很容易的方式使用 **SignalR**,那就是使用 [Abp.Web.SignalR](http://www.nuget.org/packages/Abp.Web.SignalR)。详情请参考[SignalR文档](http://www.asp.net/signalr)。
### 8.2.2 安装
#### 1. 服务器端
使用Nuget安装[Abp.Web.SignalR](http://www.nuget.org/packages/Abp.Web.SignalR)到你的项目中(通常是你的Web项目)并且在模块中添加被依赖的模块:
```csharp
[DependsOn(typeof(AbpWebSignalRModule))]
public class YourProjectWebModule : AbpModule
{
//...
}
```
然后,在你的OWIN Startup类中使用 **MapSignalR** 方法,正如你往常那样做的:
```csharp
[assembly: OwinStartup(typeof(Startup))]
namespace MyProject.Web
{
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.MapSignalR();
//...
}
}
}
```
>注意:**Abp.Web.SignalR** 依赖于 **Microsoft.AspNet.SignalR.Core**。所以,你需要安装 [Microsoft.AspNet.SignalR](https://www.nuget.org/packages/Microsoft.AspNet.SignalR)到你的Web项目中。详情请参考[SignalR文档](http://www.asp.net/signalr)。
#### 2. 客户端
脚本 **abp.signalr.js** 应该被引用到页面中。它位于 [Abp.Web.Resources](https://www.nuget.org/packages/Abp.Web.Resources) 包中(它已经被安装到启动模板中)。
我们应该在 **signalr hubs** 后引用它:
```html
<script src="~/signalr/hubs"></script>
<script src="~/Abp/Framework/scripts/libs/abp.signalr.js"></script>
```
这么做了以后,SignalR就已经恰当的配置和集成到你的项目中了。
#### 3. 建立连接
当 **abp.signalr.js** 被引用到页面后,ABP会自动的连接到你的服务器。一般我们都会这么做,但是在某些情况下你不想这样做。你可以像下面代码所示禁用自动连接:
```html
<script>
abp.signalr = abp.signalr || {};
abp.signalr.autoConnect = false;
</script>
```
在这种情况下,你可以手动调用 **abp.signalr.connect()** 函数来连接服务器。
当客户端连接到服务器时,全局事件 **"abp.signalr.connected"** 会被触发。当连接建立成功的时候,你可以注册这个事件来采取相应的行动。详情请参考[Javascript函数库](6.6ABP表现层-Javascript函数库.md)
### 8.2.3 内置功能
你可以在应用程序中使用所有的SignalR的功能。还有,在 **Abp.Web.SignalR** 中实现了一些内置功能。
#### 1. 通知
**Abp.Web.SignalR** 实现了 **IRealTimeNotifier** 接口来发送实时时间到客户端。因此,你的用户可以获得实时的推送通知。
#### 2. 在线客户端
ABP提供了 **IOnlineClientManager** 来取得在线用户的信息(如:注入IOnlineClientManager以及使用GetByUserIdOrNull, GetAllClients, IsOnline 方法)。为了能够正常工作,IOnlineClientManager需要一个通信基础设施。**Abp.Web.SignalR** 提供了这个基础设施。如果安装了SignalR,那么在应用的任何层都可以注入并使用IOnlineClientManager。
#### 3. PascalCase vs. camelCase
Abp.Web.SignalR 使用 **CamelCasePropertyNamesContractResolver** 重写了 SignalR's 默认的序列化类 **ContractResolver**。因此,在服务器端类具有 **PascalCase** 属性,而在客户端为了发送/接受对象,我们使用 **camelCase** (因为camelCase在JavaScript中更受欢迎)。如果你想在某些程序集中忽略这个,那么你可以将那些程序集添加AbpSignalRContractResolver.IgnoredAssemblies 列表中。
### 8.2.3 你的SignaR代码
使用 **Abp.Web.SignalR** 包也会简化你的 SignalR代码。假设我们想要添加一个Hub到你的应用程序中:
```csharp
public class MyChatHub : Hub, ITransientDependency
{
public IAbpSession AbpSession { get; set; }
public ILogger Logger { get; set; }
public MyChatHub()
{
AbpSession = NullAbpSession.Instance;
Logger = NullLogger.Instance;
}
public void SendMessage(string message)
{
Clients.All.getMessage(string.Format("User {0}: {1}", AbpSession.UserId, message));
}
public async override Task OnConnected()
{
await base.OnConnected();
Logger.Debug("A client connected to MyChatHub: " + Context.ConnectionId);
}
public async override Task OnDisconnected(bool stopCalled)
{
await base.OnDisconnected(stopCalled);
Logger.Debug("A client disconnected from MyChatHub: " + Context.ConnectionId);
}
}
```
为了使我们的Hub可以简单的注册到[依赖注入](225827)系统中,我们可以实现 **ITransientDependency** 接口。当然你可以根据你的需求,注册它为单例模式。我们也使用属性注入了[Session](225828)和[Logger](225830)。
SendMessage是hub的一个方法,它可以被客户端使用。在这个方法中,我们可以调用所有客户端的 getMessage函数。正如你看到的那样,我们可以使用AbpSession来获得当前的用户id(如果用户已经登录)。为了演示,我们也重写了 OnConnected 和 OnDisconnected,实际这里是不需要的。
下面是用在Hub中,用来发送/接受信息的客户端脚本:
```javascript
var chatHub = $.connection.myChatHub; //get a reference to the hub
chatHub.client.getMessage = function (message) { //register for incoming messages
console.log('received message: ' + message);
};
abp.event.on('abp.signalr.connected', function() { //register for connect event
chatHub.server.sendMessage("Hi everybody, I'm connected to the chat!"); //send a message to the server
});
```
然后,在我们需要发送信息到服务器时,我们就可以使用 **chatHub**。详情请参考[SignalR文档](http://www.asp.net/signalr)。
- 文章&教程
- Abp
- 1.1ABP总体介绍-入门介绍
- 1.2ABP总体介绍-多层架构体系
- 1.3ABP总体介绍-模块系统
- 1.4ABP总体介绍-启动配置
- 1.5ABP总体介绍-多租户
- 1.6ABP总体介绍-集成OWIN
- 2.1ABP公共结构-依赖注入
- 2.2ABP公共结构-会话管理
- 2.3ABP公共结构-缓存管理
- 2.4ABP公共结构-日志管理
- 2.5ABP公共结构-设置管理
- 2.6ABP公共结构-时区设置
- 3.1ABP领域层-实体
- 3.2ABP领域层-值对象
- 3.3ABP领域层-仓储
- 3.4ABP领域层-领域服务
- 3.5ABP领域层-工作单元
- 3.6ABP领域层-领域事件
- 3.7ABP领域层-数据过滤器
- 4.1ABP应用层-应用服务
- 4.2ABP应用层-数据传输对象
- 4.3ABP应用层-数据传输对象验证
- 4.4ABP应用层-权限认证
- 4.5ABP应用层-功能管理
- 4.6ABP应用层-审计日志
- 5.1ABP分布式服务-ASP.NET WebApi
- 5.2ABP分布式服务-动态WebApi层
- 5.3ABP分布式服务-集成OData
- 5.4ABP分布式服务-集成SwaggerUI
- 6.1ABP表现层-Mvc控制器
- 6.2ABP表现层-Mvc视图
- 6.3ABP表现层-本地化
- 6.4ABP表现层-导航栏
- 6.5ABP表现层-异常处理
- 6.6.2-AJAX
- 6.6.3-Notification
- 6.6.4-Message
- 6.6.5-UIBlockBusy
- 6.6.6-EventBus
- 6.6.7-Logging
- 6.6.8-OtherUtilities
- 6.6ABP表现层-JavascriptAPI
- 6.7ABP表现层-嵌入资源文件
- 6.8ASP.NET-Core
- 6.9CSRF和XSRF保护
- 7.1ABP后台服务-后台作业和工人
- 7.2ABP后台服务-集成Hangfire
- 8.1ABP实时服务-通知系统
- 8.2ABP实时服务-集成SignalR
- 9.1ABP基础设施层-集成Entity Framework
- 9.2ABP基础设施层-集成NHibernate
- 9.3ABP基础设施层-集成Entity Framework Core
- abp合并版160929
- md文档排版规范
- AbpZero
- 1.1ABPZero-概述
- 1.2ABPZero-安装
- 1.3ABPZero-启动模板
- 1.4ABPZero-启动模板Core
- 2.1ABPZero-多租户管理
- 2.2ABPZero-版本管理
- 2.4ABPZero-组织单位管理