SignalR 设计理念(二)
SignalR 设计理念(二)
实现客户端和服务器端的实时通讯.
前言:
客户端方法忽略大小写,主要原因基于是URL对大小写不敏感的问题,开发者之间为了更好的协同开发,定下的开发者协议。
问题阐述
- 客户端数量不确定!
- 同一个用户的客户端数量不确定(一个用户可以多处登陆)!
- 客户端连接的渠道不确定(应用程序连接、Web普通连接、WebSocket连接等)!
- 同一个用户的连接渠道不一定!
针对以上问题,你会如何设计服务器架构?
SignalR 采用 管道通讯 作为连接消息通道,使用 分配器 对消息适配(基于持久化连接抽象类
PersistentConnection
实现)。
问:
- 管道数如何区分连接渠道? [1]
举一反三:
- 客户端和服务器之间,消息是如何传递的?
核心代码(一):
public abstract class PersistentConnection
{ //持久化连接 【部分代码】
private ITransportManager _transportManager;
public virtual void Initialize(IDependencyResolver resolver)
{
_transportManager = resolver.Resolve<ITransportManager>();
}
public virtual Task ProcessRequest(HostContext context)
{
if (context == null)
{
throw new ArgumentNullException("context");
} if (!_initialized)
{
throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, Resources.Error_ConnectionNotInitialized));
} if (IsNegotiationRequest(context.Request))
{
return ProcessNegotiationRequest(context);
}
else if (IsPingRequest(context.Request))
{
return ProcessPingRequest(context);
} Transport = GetTransport(context); // 建立运输方式 if (Transport == null)
{
return FailResponse(context.Response, String.Format(CultureInfo.CurrentCulture, Resources.Error_ProtocolErrorUnknownTransport));
} string connectionToken = context.Request.QueryString["connectionToken"]; if (String.IsNullOrEmpty(connectionToken))
{
return FailResponse(context.Response, String.Format(CultureInfo.CurrentCulture, Resources.Error_ProtocolErrorMissingConnectionToken));
} string connectionId;
string message;
int statusCode; if (!TryGetConnectionId(context, connectionToken, out connectionId, out message, out statusCode))
{
return FailResponse(context.Response, message, statusCode);
} Transport.ConnectionId = connectionId; // Get the groups token from the request
return Transport.GetGroupsToken()
.Then((g, pc, c) => pc.ProcessRequestPostGroupRead(c, g), this, context)
.FastUnwrap();
}
private ITransport GetTransport(HostContext context)
{
return _transportManager.GetTransport(context);
}
}
核心代码(二):
public class TransportManager : ITransportManager
{ //运输机管理器 【部分代码】
private readonly ConcurrentDictionary<string, Func<HostContext, ITransport>> _transports = new ConcurrentDictionary<string, Func<HostContext, ITransport>>(StringComparer.OrdinalIgnoreCase);
[SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "Those are factory methods")]
public TransportManager(IDependencyResolver resolver)
{
if (resolver == null)
{
throw new ArgumentNullException("resolver");
}
Register("foreverFrame", context => new ForeverFrameTransport(context, resolver));
Register("serverSentEvents", context => new ServerSentEventsTransport(context, resolver));
Register("longPolling", context => new LongPollingTransport(context, resolver));
Register("webSockets", context => new WebSocketTransport(context, resolver));
}
// 注册运行机 (可自定义运输方式)
public void Register(string transportName, Func<HostContext, ITransport> transportFactory)
{
if (String.IsNullOrEmpty(transportName))
{
throw new ArgumentNullException("transportName");
} if (transportFactory == null)
{
throw new ArgumentNullException("transportFactory");
} _transports.TryAdd(transportName, transportFactory);
}
// 分配运输机
public ITransport GetTransport(HostContext hostContext)
{
if (hostContext == null)
{
throw new ArgumentNullException("hostContext");
} string transportName = hostContext.Request.QueryString["transport"]; if (String.IsNullOrEmpty(transportName))
{
return null;
} Func<HostContext, ITransport> factory;
if (_transports.TryGetValue(transportName, out factory))
{
return factory(hostContext);
} return null;
}
}
解析:
由连接中的
transport
参数区分,有兴趣的朋友可以下载源码深度学习 Microsoft.AspNet.SignalR。 ↩︎
SignalR 设计理念(二)的更多相关文章
- .net mvc 站点自带简易SSL加密传输 Word报告自动生成(例如 导出数据库结构) 微信小程序:动画(Animation) SignalR 设计理念(一) ASP.NET -- WebForm -- ViewState ASP.NET -- 一般处理程序ashx 常用到的一些js方法,记录一下 CryptoJS与C#AES加解密互转
.net mvc 站点自带简易SSL加密传输 因项目需要,传输数据需要加密,因此有了一些经验,现简易抽出来分享! 请求:前端cryptojs用rsa/aes 或 rsa/des加密,后端.net ...
- SignalR 设计理念(一)
SignalR 设计理念(一) 实现客户端和服务器端的实时通讯. 问题阐述 客户端提供的方法不确定! 客户端的方法参数不确定! 不同的名称和参数要分别调用指定的方法! 调用客户端方法时,忽略大小写! ...
- asp.net core 使用 signalR(二)
asp.net core 使用 signalR(二) Intro 上次介绍了 asp.net core 中使用 signalR 服务端的开发,这次总结一下web前端如何接入和使用 signalR,本文 ...
- SignalR入门二、使用 SignalR 2 实现服务器广播
一.概述 这篇教程通过实现一个股票报价的小程序来讲解如何使用SignalR进行服务器端的推送,服务器会模拟股票价格的波动,并把最新的股票价格推送给所有连接的客户端,最终的运行效果如下图所示. 教程:使 ...
- SignalR 教程二 服务端广播
转帖官方教程:Tutorial: Server Broadcast with SignalR 2 http://www.asp.net/signalr/overview/getting-started ...
- 一、SignalR使用心得
一.通讯模式 以往,我们聊天发消息模式(单体发送消息或通知)-好友(一对一).群组(一对多),方便管理好友-分组方式. 那么聊天和好友管理参考qq,刷新分组标签也页面就会从新加载分组列表和分组内好友列 ...
- Angular 初体验
事情起源当初一个简单的截屏然后推流出去的工具,这个工具当初我用winform简单实现了下,然后因公司业余,添加许多程序包,需要自动管理这些程序包,包含下载更新上传等,以及与后台交互,学生老师提醒,自动 ...
- 华为云Stack首席架构师:打造“称手”的数字化工具,答好政企IT数字化转型这道必选题
摘要:数字化转型是一号位工程,数字化的工具本身就是企业的核心竞争力. 本文分享自华为云社区<华为云Stack首席架构师:打造"称手"的数字化工具,答好政企IT数字化转型这道必 ...
- 基于SignalR的消息推送与二维码描登录实现
1 概要说明 使用微信扫描登录相信大家都不会陌生吧,二维码与手机结合产生了不同应用场景,基于二维码的应用更是比较广泛.为了满足ios.android客户端与web短信平台的结合,特开发了基于Singl ...
随机推荐
- ios web input 内边阴影
ios网页中,默认input上部有阴影,去除方法: -webkit-appearance: none;
- wordpress 下载主题模板、更新报错 No working transports found解决办法
出错原因是PHP没有开启curl. windows下开启方法如下 1. 将php.ini中的;extension=php_curl.dll前的分号去掉, 2. 将php中libeay32.ll, ss ...
- ECMAScript6新特性之String API
填充到指定长度,默认使用空格填充. 一 左填充 var arr = []; for(var i=0;i<20;i++){ var str = (i+'').padStart(2,'0'); ar ...
- TZOJ 1242 求出前m大的数(预处理)
描述 给定一个包含N(N<=3000)个正整数的序列,每个数不超过5000,对它们两两相加得到的N*(N-1)/2个和,求出其中前M大的数(M<=10000)并按从大到小的顺序排列. 输入 ...
- 'wmic' 不是内部或外部命令,也不是可运行的程序 解决方法
在环境变量中查看变量名Path下的变量值是否有以下讯息? 如没有复制(Ctrl+C).黏贴(Ctrl+V)→确定即可. %SystemRoot%;%SystemRoot%\system32;%Syst ...
- 761A Dasha and Stairs
A. Dasha and Stairs time limit per test 2 seconds memory limit per test 256 megabytes input standard ...
- linux 下安装gult
本文假设你之前没有用过任何任务脚本(task runner)和命令行工具,一步步教你上手Gulp.不要怕,它其实很简单,我会分为五步向你介绍gulp并帮助你完成一些惊人的事情.那就直接开始吧. 第一步 ...
- [BAT]cmd命令之 cd /d %~dp0
cd /d %~dp0是什么意思啊?批处理文件中的一条语句意思是 更改当前目录为批处理本身的目录 有些晕吧?不急,我举例 比如你有个批处理a.bat在D:\qq文件夹下 a.bat内容为 cd /d ...
- [开源,学习,分享]UWP第三方简书客户端分享
简介 Windows10正式版发布到现在,我利用零零碎碎的一些时间对UWP进行一些学习,也基于这门技术开发了一个第三方的简书App. 基本界面 优酷视频: http://v.youku.com/v_s ...
- MetroApp保存UIEment为图片
写本文的起因是想截取Metro App画面作为图片来使用Win8的共享. 话说自从大MS的客户端UI技术进入XAML时代之后,每次截屏的代码都不太一样,无论silverlight.WPF还是Windo ...