博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
SignalR 设计理念(二)
阅读量:4973 次
发布时间:2019-06-12

本文共 4046 字,大约阅读时间需要 13 分钟。

SignalR 设计理念(二)

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

前言:

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

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

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

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

问:

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

举一反三:

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

核心代码(一):

public abstract class PersistentConnection { //持久化连接 【部分代码】 private ITransportManager _transportManager; public virtual void Initialize(IDependencyResolver resolver) {     _transportManager = resolver.Resolve
(); } 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
> _transports = new ConcurrentDictionary
>(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
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
factory; if (_transports.TryGetValue(transportName, out factory)) { return factory(hostContext); } return null; }}
解析:

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

转载于:https://www.cnblogs.com/vbing/p/10012765.html

你可能感兴趣的文章
开发WINDOWS服务程序
查看>>
httpencode编码
查看>>
cross socket和msgpack的数据序列和还原
查看>>
解决跨操作系统平台JSON中文乱码问题
查看>>
DELPHI搭建centos开发环境
查看>>
IdHTTPServer允许跨域访问
查看>>
更新.net core 3.0,dotnet ef命令无法使用的解决办法
查看>>
React躬行记(13)——React Router
查看>>
前端利器躬行记(1)——npm
查看>>
前端利器躬行记(2)——Babel
查看>>
前端利器躬行记(6)——Fiddler
查看>>
Forbidden You don't have permission to access / on this server.
查看>>
Intellij Idea新建web项目(转)
查看>>
用JAVA编写浏览器内核之实现javascript的document对象与内置方法
查看>>
centos iptables
查看>>
unity3d 移动与旋转 2
查看>>
寻找二叉查找树中比指定值小的所有节点中最大的那个节点
查看>>
如何设置输入框达到只读效果
查看>>
RT3070 USB WIFI 在连接socket编程过程中问题总结
查看>>
MIS外汇平台荣获“2013年全球最佳STP外汇交易商”
查看>>