mormot2事件驱动模型

mormot2事件驱动模型

异步套接字访问和事件循环是最佳服务器可伸缩性的关键。

事件非常抽象,实际上只是每个连接上的基本 R/W 操作,与“tag”相关联。

然后在这些基本的套接字驱动事件之上编写了全新的 HTTP/1.0、HTTP/1.1 和 WebSockets 堆栈。它们没有阻塞线程,而是使用内部状态机,它比线程轻得多,甚至比协程/goroutine 更轻。每个连接只是一个类实例,它维护每个客户端/服务器通信的状态,并访问它自己的套接字。

mORMot异步 TCP 服务器默认有一个线程接受连接,一个线程轮询未决事件(调用方法GetOne,然后一组专用线程使用读/写/关闭事件(通过GetOnePending方法)。我们使用了尽可能多的非阻塞结构,我们通过重复使用相同的缓冲区来最小化内存分配,例如用于标头或小响应,我们在每种情况下都尽可能选择最好的锁,以便该服务器可以很好地平滑地扩展。而且使用简单,因为处理一个新的协议就像继承和编写一个新的连接类一样简单。

mormot2的异步服务器类现在看起来稳定且快速(据报道比 nginx 快两倍,比 nodejs 快六倍!)。

事件驱动socket访问

什么是 socket fd ?就是网络 fd,撇开底层和协议细节,网络通信和文件读写从接口上有本质区别吗?其实没啥区别,不就是读过来和写过去嘛,简称 IO 。
io multiplexing module(io多路复用模块)
event loop(事件循环)
event handler(事件处理程序)

TPollSockets

mormot.net.sock.pas

///实现多个套接字的有效轮询
//-将维护一个TPollSocketAbstract实例池,以监视
//一组活动连接的传入数据或传出可用性
//-调用Subscribe/Unsubscribe以设置受监视的套接字
//-从主线程调用GetOne,也可以从子线程调用GetOnePending
TPollSockets=class(TPollAbstract)
...
///初始化套接字轮询
constructor Create(aPollClass: TPollSocketClass = nil);
///完成套接字轮询,并释放所有使用的内存
destructor Destroy; override;
///在一个指定的TSocket和标记上跟踪修改
function Subscribe(socket: TNetSocket; events: TPollSocketEvents;
      tag: TPollSocketTag): boolean; override;
///在一个指定的TSocket和标记上停止状态修改跟踪
procedure Unsubscribe(socket: TNetSocket; tag: TPollSocketTag); virtual;
///检索下一个挂起的通知,或让轮询等待新的
function GetOne(timeoutMS: integer; const call: RawUtf8;
      out notif: TPollSocketResult): boolean; virtual;
///检索下一个挂起的通知
function GetOnePending(out notif: TPollSocketResult; const call: RawUtf8): boolean;
///让轮询检查挂起的事件,并将其发送到fPending结果
function PollForPendingEvents(timeoutMS: integer): integer; virtual;
///手动将一个事件附加到挂起的节点
procedure AddOnePending(aTag: TPollSocketTag; aEvents: TPollSocketEvents;
      aNoSearch: boolean);
///通知任何GetOne等待方法停止其轮询循环
procedure Terminate; override;
TPollSocketEvent = (
    pseRead,
    pseWrite,
    pseError,
    pseClosed);
  TPollSocketEvents = set of TPollSocketEvent;

  TPollSocketResult = record
    tag: TPollSocketTag;
    events: TPollSocketEvents;
  end;
  TPollSocketResults = record
    Events: array of TPollSocketResult;
    Count: PtrInt;
  end;

 

posted @ 2023-03-07 08:47  delphi中间件  阅读(365)  评论(0编辑  收藏  举报