SignalR 设计理念(二)

SignalR 设计理念(二)

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

前言:

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

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

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

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

问:

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

举一反三:

  1. 客户端和服务器之间,消息是如何传递的?

核心代码:

public abstract class PersistentConnection
{ //持久化连接 【部分代码】

 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();
 }
}

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。?

原文地址:https://www.cnblogs.com/vbing/p/10012765.html

时间: 2024-10-14 21:24:02

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

Nginx+SignalR+Redis(二)windows

接上篇:此篇主要讲解signalr使用nginx后遇到的问题. 首先发布signalr服务端多个站点,为了简单只发布了两个站点类似:一个服务端端口8090一个8091 然后配置Nginx具体安装下载就不一一介绍,可以自行百度安装.现在只介绍配置nginx.config中的项,因为在此遇到了许多坑 先将ngixn.con中的代码贴出来. events { worker_connections 1024;} http { include mime.types; default_type applic

SignalR 教程二 服务端广播

转帖官方教程:Tutorial: Server Broadcast with SignalR 2 http://www.asp.net/signalr/overview/getting-started/tutorial-server-broadcast-with-signalr This tutorial shows how to create a web application that uses ASP.NET SignalR 2 to provide server broadcast fu

ASP.NET Core SignalR (二):支持的平台

此为系列文章,对MSDN ASP.NET Core SignalR 的官方文档进行系统学习与翻译.其中或许会添加本人对 ASP.NET Core 的浅显理解. 服务端系统要求 只要是ASP.NET Core支持的服务器平台都会支持ASP.NET Core SignalR. Javascript 客户端 JavaScript客户端 运行在NodeJS 8 以及后续版本中,支持的浏览器如下: 浏览器 版本 Microsoft Edge Current† Mozilla Firefox Current

[Asp.net 开发系列之SignalR篇]专题二:使用SignalR实现酷炫端对端聊天功能

一.引言 在前一篇文章已经详细介绍了SignalR了,并且简单介绍它在Asp.net MVC 和WPF中的应用.在上篇博文介绍的都是群发消息的实现,然而,对于SignalR是为了实时聊天而生的,自然少了不像QQ一样的端对端的聊天了.本篇博文将介绍如何使用SignalR来实现类似QQ聊天的功能. 二.使用SignalR实现端对端聊天的思路 在介绍具体实现之前,我先来介绍了使用SignalR实现端对端聊天的思路.相信大家在前篇文章已经看到过Clients.All.sendMessage(name,

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

1 概要说明 使用微信扫描登录相信大家都不会陌生吧,二维码与手机结合产生了不同应用场景,基于二维码的应用更是比较广泛.为了满足ios.android客户端与web短信平台的结合,特开发了基于SinglarR消息推送机制的扫描登录.本系统涉及到以下知识点:     SignalR:http://signalr.net/ 这官网,ASP.NET SignalR 是为 ASP.NET 开发人员提供的一个库,可以简化开发人员将实时 Web 功能添加到应用程序的过程.实时 Web 功能是指这样一种功能:当

ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(二) 之 ChatServer搭建,连接服务器,以及注意事项。

上篇:ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(一) 之 基层数据搭建,让数据活起来(数据获取) 上一篇我们已经完成了初步界面的搭建工作,本篇将介绍IM的核心内容了,就是SignalR的Hub类.整个即时通讯机制都是以它为基础的.至于原理我也不再讲解,讲了也不如专业的文章讲得好.所以我们直接看业务,上代码.有一部分原理 在文章 ASP.NET SignalR 与LayIM配合,轻松实现网站客服聊天室(二) 实现聊天室连接 (当时是LayIM1.0版本).原理

Asp.NET MVC 使用 SignalR 实现推送功能二(Hubs 在线聊天室 获取保存用户信息)

简单介绍 关于SignalR的简单实用 请参考 Asp.NET MVC 使用 SignalR 实现推送功能一(Hubs 在线聊天室) 在上一篇中,我们只是介绍了简单的消息推送,今天我们来修改一下,实现保存消息,历史消息和用户在线 由于,我这是在一个项目([无私分享:从入门到精通ASP.NET MVC]从0开始,一起搭框架.做项目 目录索引)的基础上做的,所以使用到的一些借口和数据表,不详细解析,只是介绍一下思路和实现方式,供大家参考 用户登录注册信息 当用户登录之后,我们注册一下用户的信息,我们

SignalR循序渐进(二)

接上一篇,文章末尾抛出了2个问题: 能不能让客户端声明一个强类型的方法列表呢?这样首先不容易写错. 同样的,能不能让服务端声明一个强类型的方法列表给客户端调用呢? 如果要让客户端的方法以强类型出现在服务端,同样的,服务端的方法也以强类型出现在客户端,那就必须声明类似契约一样的载体.比如: public interface IChatClient { void broadcast(string name, string message); } public interface IChatHub {

ABP源码分析三十二:ABP.SignalR

Realtime Realtime是ABP底层模块提供的功能,用于管理在线用户.它是使用SignalR实现给在线用户发送通知的功能的前提 IOnlineClient/OnlineClient: 封装在线用户的信息 OnlineClientManager/IOnlineClientManager: 用于提供基本维护在线用户的方法.其内部维护了一个字典来保存在线的客户信息. SingalR SignalRRealTimeNotifier: 实现了给在线用户发送通知的功能.其从IOnlineClien