QSocket 是 QDAC 开源组件的一个重要的组成部分,终于要开始开工了,为了方便大家了解 QSocket,对 QSocket 的总体设计的一些想法,我在这里给大家简要的描述一下。

首先,QSocket 同 QDAC 的其它组成部分一样,是跨平台的,这意味着你可以在不同的操作系统中,体验 QSocket 为你带来的良好体验。

其次,QSocket 是 Delphi 的原生代码,所以不会依赖于其它第三方库(QDAC 自身的不算:-:)。

其三,QSocket 会基于各个操作系统自身,进行针对性的优化,换句话说,IOCP/KQueue/EPOLL 都将在里面看到它的身影。

老末,QSocket 将是一个基于异步的 IO 框架,虽然会有一些同步的方法,不过异步是核心,同步是封装而已。

好了,现在进入总体的框架描述部分。

QSocket 的设计理念中包含以下几个部分:

  1. IQTransport
    Transport,顾名思议就是一个传输港。它来负责将数据传送到目标,这里目标包括两个含义:
    首先是发送到目标,则 IQTransport 负责将数据传递给目标地址。但具体是否传送成功,取决于 Transport 所使用的协议及实现;
    其次是接收后派发到目标,则 IQTransport 负责将接收到的数据,传递给具体的处理函数,来完成对数据的处理。
    通俗点讲,IQTransport 就是一个港口,负责货物的打包、装运和分流,为此它提供了:

    1. 用于指定本地要监听的地址及端口的 Bindings 列表,也可以通过简单的指定 LocalPort 来在所有地址的指定端口上监听通讯(仅对TCP/UDP有效,其它协议该属性可能无意义);
    2. 用于管理已经建立的连接的 Connections 列表;
    3. 用于广播数据的 Broadcast 函数;
    4. 用于对要传送的数据进行打包操作的编码处理器 Codecs;
    5. 用于确定要将接收到的数据如果处理的派发器列表 Dispatchers;
    6. 其它由 IQTransport 的接口实现提供的其它属性及方法
  2. IQRequest
    Request,请求。在 QSocket 中,一次请求+回应构成一个请求。比如,我们向服务器端发送一个命令,此时就会生成一个请求,服务器返回处理结果,这个请求的处理就结束了。我们再向服务器发送后续的命令,就是新的请求了。有一个概念需要大家明白,请求未必有回应,所以有求必应在 QSocket 中并不是一个必然的概念。由于请求的发送及处理都需要时间,如果此处用同步等待的方法来编程,很明显会降低整个系统的效率,所以,IQRequest 的接口实现了异步发送接口。IQRequest 提供的主要内容如下:
    1. 请求 ID,一个无符号32位整数,它具体的意义,取决于具体的实现,一般用它来标记一次唯一的请求和其对应的回复;
    2. 优先级 Priority,一个枚举类型,用于指定请求发送的优先级。如果你同时投递了几个请求,则优先级高的请求将会优先发送。但是,这个也取决于具体的实现。QSocket 本身会提供一个自己封装的多会话并行发送协议,它允许在现有会话发送过程中插入高优先级的会话发送,以避免低优先级的长时间数据传输请求影响普通或紧急业务数据的传送。不过这需要服务器端也要兼容 QSocket 的这个协议。在一般的场景实现中,阿门,忽略它吧,很少有协议支持它。
    3. 关联的连接对象 Connection,这个不用说啥了。
    4. 记录请求内容的 RequestData,在接收到请求后,要处理的数据都在里面了。
    5. 记录回应内容的 ReplyData,在接到回应后,需要处理的数据都在里面了。
    6. 错误代码 ErrorCode 和错误提示 ErrorMsg,这个就没啥可说的了。
    7. 发送请求的函数 PostRequest 和 SendRequest,一个是异步,一个是同步。异步的需要提供一个回调函数,以便在得到结果时响应,如果不提供,则意味着忽略返回结果的处理。
    8. 发送回应的函数 PostReply。
  3. IQConnection
    Connection,连接,这个搞网络编程的都明白是啥,就不多说。需要注意一点,在 QSocket 中,UDP 协议也是有连接的,只不过这种连接是有限制的:
    首先,由于 UDP 协议本身是无连接的,超过一段时间未收发数据,会被网关给断掉,所以这个连接本身会内置一些辅助的连接保持功能(如无数据,每隔10秒会发送一个无载荷的空 UDP 数据包,以保持网关会话的有效性)。
    其次,UDP 协议本身是不保证数据的准确到达的,所以基于 UDP 的连接本身同样也不保证这一点。但 QSocket 会提供更高一级别的封装,来保证 UDP 协议达到类似于 TCP 的有连接效果,同样,这种封装协议的代价就是服务器端也需要采用同样的协议。
    IQConnection 提供的主要内容如下:
    1. 本地绑定的地址 LocalAddr;
    2. 远程绑定的地址 RemoteAddr;
    3. 创建一个新请求的函数 NewRequest;
    4. 发送和接收数据的接口:Post/Send/Recv/Peek。
  4. IQDataCodec
    Data Codec ,数据编码和解码接口。主要用于数据的加密、压缩以及其它打包的处理工作。一次传输过程,可能要经过多个 IQDataCodec 进行流水线处理,所以它的工作是否正常,严重依赖于发送和接收端的设置是否一致,包括顺序。比如,我们先压缩后加密和先加密,后压缩就是两个不同的选择。编码的过程,是按照 IQDataCodec 的添加顺序进行的,解码的过程,则是按照添加顺序的逆序执行的。
    IQDataCodec 提供的主要内容如下:
    1. 编码函数 Encode
    2. 解码函数 Decode
    3. 编解码器名称 Name
  5. IQCommand
    Command,命令。它的主要作用是配合 IQCommandDispatcher,管理支持的请求命令的处理函数。一般来说,一个命令只应该有一个处理函数,不过 QSocket 支持一个命令交由多个函数来处理,它会在接收到请求后,传递给第一个处理函数,如果第一个处理函数未设置 AHandled 参数为 true,则会交给第二个函数处理,直到所有的处理函数都调用完成或者 AHandled 在某个处理函数中返回了 true,才会中止处理。这主要是方便一些通知类型的命令的处理。
    IQCommand 提供的主要内容如下:
    1. 命令 Id,是否有意义取决于具体的协议,这一般用于基于数值命令驱动的处理
    2. 命令路径 NamePath,这一般用于字符类命令驱动的协议的处理
    3. 命令响应列表的管理函数及属性:Add/Delete/Remove/Clear/Count/Handlers
    4. 命令处理函数 HandleCommand
  6. IQCommandDispatcher
    Command Dispatcher,命令调度器。它负责将接收的请求中的内容进行解码,取出其中的命令,然后查找注册的 IQCommand,并调用相应的 IQCommand 的 HandleCommand 方法进行实际的处理。
    IQCommandDispatcher 提供的主要内容如下:
    1. 命令注册及管理函数、属性:Add/Delete/Remove/Clear/ByNamePath/ById/Count/Commands
    2. 判断是否能够派发指定的数据内容的函数:CanDispatch
    3. 执行实际派发的函数:Dispatch
  7. IQDataBuffer
    Data Buffer,数据缓冲区实现。它支持四种不同的缓冲区,以便根据实际需要来创建不同类型的缓冲区(关于它实现的主要内容省略):
    1. 内存缓冲区,直接使用 NewBuffer 就可以创建一个内在缓冲区对象;
    2. 文件缓冲区,直接使用 NewBuffer ,将要保存缓冲内容的文件名当做参数传递,就可以创建一个文件缓冲对象。这适用于文件或大型的数据请求的处理。
    3. 流缓冲区,直接使用 NewBuffer,将一个 TStream 类型的对象传递进去做为参数,就可以创建一个流缓冲对象,文件缓冲区实际上也是基于它实现的。
    4. 共享缓冲区,直接使用 ShareBuffer 函数,将一个已有的缓冲区接口做为参数传入,就可以创建一个共享的流缓冲对象,通过 ShareBuffer 返回的 IQDataBuffer 可以独立使用,共同访问同一个源 IQDataBuffer 的数据。通过 ShareBuffer 访问源数据的内容是线程安全的。
  8. IQSocketFactory
    Factory,就是工厂了。这个工厂是一个不负责任的工厂,只负责生产出 Transport 和 Connection 对象,不负责售后。它的主要目的是简化上层的各种东西的创建,如果我们要创建一个面向Tcp 连接,则我们可以调用 SocketFactory.NewCo6nnection(‘tcp://connection’) 得到一个 TCP 连接对象,或者我们直接调用 SocketFactory.NewConnection(‘tcp://connection?dst=192.168.0.1:980’) 来创建一个连接到 192.160.0.1 的 980 端口的连接对象。
    IQSocketFactory 生产以下内容:
    1. IQTransport,URI 的 host 部分为 transport,Scheme 部分则由相应的 IQTransport 实现自己约定。
    2. IQConnection,URI 的 host 部分为 connection,Scheme 部分同样由相应的 IQConnection 实现自己约定。
    3. IQDataBuffer,URI 的 host 部分为 buffer,scheme 包括:mem/file 两种,不支持流缓冲区和共享缓冲区
    4. IQCommandDispatcher,URI 的 host 部分为 dispatcher,Scheme 部分同样由相应的 IQCommandDispatcher 实现自己约定。
    5. IQRequest,URI 的 host 部分为 request,一般更推荐调用 IQConnection 的 NewRequest 来实现。Scheme 部分同样由相应的 IQRequest 实现自己约定。
  9. TQAddr
    Addr(ess),地址的归一化封装。在 QSocket 中,各种协议的不同地址表达形式,都通过 TQAddr 进行封装。它支持IPv4/IPv6/UnixDomain/NamePipe/FilePath类型的地址管理,主要提供的内容如下:
    1. 类型转换重载 Implicit,实现将 IPv4/IPv6 地址直接转换为相应的 TQAddr 结构
    2. 生成相应类型的 TQAddr 结构的辅助函数:MakeIPv4/MakeIPv6/MakeAddr
    3. 生成 IPv4/IPv6 协议对应接口类型的 ToIPAddr
    4. 地址类型属性:AddrType
    5. 完整地址文本表示:Text
    6. 仅地址的文本表示:AddrOnly
    7. 端口号:Port
    8. 其它属性:AsIPv4/AsIPv6

上述这些部分构成了 QSocket 的核心,后面更复杂的是实现上面说的这一堆东西。其中,TQAddr 和 IQDataBuffer 的接口已经实现完成,但 QSocket 的万里长征,这才是第一步,希望在开发和测试过程中,大家都多多参与。

附:QSocket 通讯过程示意图

EPollIOCPKQueue跨平台通讯

http://blog.qdac.cc/?p=4408

QSocket 总体设计框架说明(观赏)的更多相关文章

  1. JAVA车票管理系统(简单GUI)

    一.    需求分析 1.设计题目:车票管理系统 用JAVA语言和数据结构知识设计设计车票管理系统.要求如下所述: 一车站每天有n个发车班次,每个班次都有一个班次号(1.2.3…n),固定的发车时间, ...

  2. GIS在水利中的应用

    摘要  GIS具有数据存储.查询.统计.图形显示.分析.模拟.决策和预测等功能,在水利中得到越来越广泛的应用,可谓水利现代化的“火车头”. 关键词 GIS 水利 应用 地理信息系统GIS通常泛指用于获 ...

  3. leveldb 源码--总体架构分析

    一 本文目的 对leveldb的总体设计框架分析(关于leveldb基本原理,此文不做阐述,读者可以自行检索文章阅读即可),对leveldb中底层数据存储数据格式,内存数据模型,compact,版本管 ...

  4. Dubbo源码学习总结系列三 dubbo-cluster集群模块

    Dubbo集群模块的目的是将集群Invokers构造一个透明的Invoker对象,其中包含了容错机制.负载均衡.目录服务(服务地址集合).路由机制等,为RPC层提供高可用.高并发.自动发现.可治理的S ...

  5. 【开源】OSharp框架解说系列(1):总体设计及系列导航

    系列文章导航 [开源]OSharp框架解说系列(1):总体设计 [开源]OSharp框架解说系列(2.1):EasyUI的后台界面搭建及极致重构 [开源]OSharp框架解说系列(2.2):EasyU ...

  6. [连载]《C#通讯(串口和网络)框架的设计与实现》-2.框架的总体设计

    目       录 C#通讯(串口和网络)框架的设计与实现... 1 (SuperIO)- 框架的总体设计... 1 第二章           框架总体的设计... 2 2.1           ...

  7. 基于C/S架构的3D对战网络游戏C++框架 _02系统设计(总体设计、概要设计)

    本系列博客主要是以对战游戏为背景介绍3D对战网络游戏常用的开发技术以及C++高级编程技巧,有了这些知识,就可以开发出中小型游戏项目或3D工业仿真项目. 笔者将分为以下三个部分向大家介绍(每日更新): ...

  8. OSharp框架总体设计

    OSharp框架解说系列(1):总体设计 〇.前言 哈,距离前一个系列<MVC实用构架设计>的烂尾篇(2013年9月1日)已经跨了两个年头了,今天是2015年1月9日,日期已经相映,让我们 ...

  9. 基于MEF的插件框架之总体设计

    基于MEF的插件框架之总体设计 1.MEF框架简介 MEF的全称是Managed Extensibility Framework(MEF),其是.net4.0的组成部分,在3.5上也可以使用.熟悉ja ...

随机推荐

  1. iOS 取消多余tableView的横线的写法

    - (void)setExtraCellLineHidden: (UITableView *)tableView{ UIView *view =[ [UIView alloc]init]; view. ...

  2. CocoaPods详解之(三)----制作篇

    CocoaPods详解之----制作篇 作者:wangzz 原文地址:http://blog.csdn.net/wzzvictory/article/details/20067595 转载请注明出处 ...

  3. HDU1074 Doing Home Work - 状压dp

    传送门 题目大意: 有n(\(\le 15\))个作业,每个作业有个name, deadline(截止日期),cost(做作业花的时间),如果没有按时完成某个作业,惩罚分数为超出的时间,求一个合理的顺 ...

  4. OpenCV中CvSVM部分函数解读

    CvSVM::predict函数解析:无论是Mat接口还是CvMat接口终于都是通过指针的形式调用的.也就是终于都是调用的下面函数实现的 float CvSVM::predict( const flo ...

  5. Azure 与 AI

    微软 Build 2017 开发者大会:Azure 与 AI 的快速发展   欢迎大家持续关注葡萄城控件技术团队博客,更多更好的原创文章尽在这里~~ 一年一度的微软 Build 大会准时起航,本年度大 ...

  6. linux 时间同步ntp

    配置前准备:关闭防火墙,配置好hosts,ssh免密登录 1.选定同步的标准,我是以hadoop002(设置为当前时间)作为同步标准,hadoop003(时间是2018年3月21,使用date -s进 ...

  7. xml报错(xsd):Failed to read schema document

    <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLoc ...

  8. jQuery memory&unique&stopOnfalse

    memory:保持以前的值,将添加到这个列表的后面的最新的值立即执行调用任何回调 (像一个递延 Deferred). 回调函数是从异步队列Deferred分离出来的,所以很多的接口设计都是为了契合De ...

  9. Distinct去除重复项

    之前在做权限模块时,因不同角色可能拥有相同的菜单,导致呈现在浏览器上时出现重复菜单项,所以需要在获取用户拥有菜单项时需要过滤重复项, 用到了Distinct,两个重载 public static IQ ...

  10. WPF字体图标——IconFont

    原文:WPF字体图标--IconFont 版权声明:本文为[CSDN博主:松一160]原创文章,未经允许不得转载. https://blog.csdn.net/songyi160/article/de ...