SignalR 设计理念(二)

实现客户端和服务器端的实时通讯.

前言:

客户端方法忽略大小写,主要原因基于是URL对大小写不敏感的问题,开发者之间为了更好的协同开发,定下的开发者协议。

问题阐述
  1. 客户端数量不确定!
  2. 同一个用户的客户端数量不确定(一个用户可以多处登陆)!
  3. 客户端连接的渠道不确定(应用程序连接、Web普通连接、WebSocket连接等)!
  4. 同一个用户的连接渠道不一定!

针对以上问题,你会如何设计服务器架构?

SignalR 采用 管道通讯 作为连接消息通道,使用 分配器 对消息适配(基于持久化连接抽象类PersistentConnection实现)。

问:

  1. 管道数如何区分连接渠道? [1]

举一反三:

  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;
}
}
解析:

  1. 由连接中的transport参数区分,有兴趣的朋友可以下载源码深度学习 Microsoft.AspNet.SignalR↩︎

SignalR 设计理念(二)的更多相关文章

  1. .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 ...

  2. SignalR 设计理念(一)

    SignalR 设计理念(一) 实现客户端和服务器端的实时通讯. 问题阐述 客户端提供的方法不确定! 客户端的方法参数不确定! 不同的名称和参数要分别调用指定的方法! 调用客户端方法时,忽略大小写! ...

  3. asp.net core 使用 signalR(二)

    asp.net core 使用 signalR(二) Intro 上次介绍了 asp.net core 中使用 signalR 服务端的开发,这次总结一下web前端如何接入和使用 signalR,本文 ...

  4. SignalR入门二、使用 SignalR 2 实现服务器广播

    一.概述 这篇教程通过实现一个股票报价的小程序来讲解如何使用SignalR进行服务器端的推送,服务器会模拟股票价格的波动,并把最新的股票价格推送给所有连接的客户端,最终的运行效果如下图所示. 教程:使 ...

  5. SignalR 教程二 服务端广播

    转帖官方教程:Tutorial: Server Broadcast with SignalR 2 http://www.asp.net/signalr/overview/getting-started ...

  6. 一、SignalR使用心得

    一.通讯模式 以往,我们聊天发消息模式(单体发送消息或通知)-好友(一对一).群组(一对多),方便管理好友-分组方式. 那么聊天和好友管理参考qq,刷新分组标签也页面就会从新加载分组列表和分组内好友列 ...

  7. Angular 初体验

    事情起源当初一个简单的截屏然后推流出去的工具,这个工具当初我用winform简单实现了下,然后因公司业余,添加许多程序包,需要自动管理这些程序包,包含下载更新上传等,以及与后台交互,学生老师提醒,自动 ...

  8. 华为云Stack首席架构师:打造“称手”的数字化工具,答好政企IT数字化转型这道必选题

    摘要:数字化转型是一号位工程,数字化的工具本身就是企业的核心竞争力. 本文分享自华为云社区<华为云Stack首席架构师:打造"称手"的数字化工具,答好政企IT数字化转型这道必 ...

  9. 基于SignalR的消息推送与二维码描登录实现

    1 概要说明 使用微信扫描登录相信大家都不会陌生吧,二维码与手机结合产生了不同应用场景,基于二维码的应用更是比较广泛.为了满足ios.android客户端与web短信平台的结合,特开发了基于Singl ...

随机推荐

  1. ECMAScript5之JSON对象属性的遍历顺序

    测试浏览器 Chrome.Safari 一 键可以用parseInt解析成整数的,按数值升序顺序. var intObj = { '3.3' : 3.3, '2' : 222, '1' :111 } ...

  2. Hibernate查询方式(补)

    -----------------siwuxie095                             Hibernate 查询方式         1.对象导航查询     根据已经加载的对 ...

  3. 【vs2010】转换到 COFF 期间失败: 文件无效或损坏

    不知怎么本来编译好好的VS2010环境,忽然出现“转换到COFF 期间失败:文件无效或损坏”的链接错误.花了好多天,试了好多方法,最终解决了这个问题. 现在罗列一下这几种解决方案: 方案1:      ...

  4. 836. Rectangle Overlap 矩形重叠

    [抄题]: A rectangle is represented as a list [x1, y1, x2, y2], where (x1, y1) are the coordinates of i ...

  5. 带最小值操作的栈 · Min Stack

    [抄题]: 实现一个带有取最小值min方法的栈,min方法将返回当前栈中的最小值. 你实现的栈将支持push,pop 和 min 操作,所有操作要求都在O(1)时间内完成. [思维问题]: [一句话思 ...

  6. git设置别名alias

    每次用git拉去版本库都很烦,特别是要从非origin源,非master分支, 例如 git pull gitlab mybranch ,这样很蛋疼. 1.写个sh去处理 2.可以通过git的别名设置 ...

  7. 使用Linux之安装jdk 7

    工具/原料   jdk7源码安装压缩包 方法/步骤     卸载OpenJDK rpm -qa | grep java rpm -e --nodeps java-1.6.0-openjdk-1.6.0 ...

  8. 对于Android开发,啥是高级工程师?

    最近一直在思考自己的技术方向.新的技术永远都是层出不穷,kotlin,flutter,小程序,轻应用等等,但是作为一个老鸟,新的东西,永远都是学不完的,想在新的技术上迭代学习出一个新高度,而增加自己的 ...

  9. 关于bootstrap的认识

    学习一个框架最好的方法当然就是去它的官网查看它的官方文档,看看官网是怎么描述这个框架的吧------Sleek, intuitive, and powerful front-end framework ...

  10. cmake 头文件 库文件 链接库

    原文地址:http://www.cnblogs.com/binbinjx/p/5626916.html 1. 添加头文件目录INCLUDE_DIRECTORIES 语法: include_direct ...