GatewayWorker框架的详解和应用

2024-09-05 07:20

本文主要是介绍GatewayWorker框架的详解和应用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、介绍

1. 简介

GatewayWorker基于Workerman开发的一个项目框架,用于快速开发TCP长连接应用,例如app推送服务端、即时IM服务端、游戏服务端、物联网、智能家居等等

GatewayWorker使用经典的Gateway和Worker进程模型。Gateway进程负责维持客户端连接,并转发客户端的数据给BusinessWorker进程处理,BusinessWorker进程负责处理实际的业务逻辑(默认调用Events.php处理业务),并将结果推送给对应的客户端。Gateway服务和BusinessWorker服务可以分开部署在不同的服务器上,实现分布式集群。

GatewayWorker提供非常方便的API,可以全局广播数据、可以向某个群体广播数据、也可以向某个特定客户端推送数据。配合Workerman的定时器,也可以定时推送数据。

 2. 特性

1、基于Workerman开发
GatewayWorker是基于Workerman开发的

2、基于Gateway、Worker进程模型
GatewayWorker使用经典的Gateway和Worker进程模型。Gateway进程负责维持客户端连接,并转发客户端的数据给Worker进程处理;Worker进程负责处理实际的业务逻辑,并将结果推送给对应的客户端。Gateway服务和Worker服务可以分开部署在不同的服务器上,实现分布式集群。

3、支持分布式部署
GatewayWorker可以非常方便实现分布式部署,Gateway服务和Worker服务都可以分开部署在不同的服务器集群上。并且操作简单、容易扩容、上下线用户无感知。

4、支持高并发
Gateway进程只负责网络IO,Worker进程负责业务逻辑。其中每个Gateway进程可以维持上万的并发连接,多个Gateway进程可以维持数十万甚至百万的并发连接,Gateway集群则可以维持千万级别的并发连接。

5、支持全局广播或者向任意客户端推送数据
GatewayWorker提供非常方便的API,可以全局广播数据、可以向某个群体广播数据、也可以向某个特定客户端推送数据。配合Workerman的定时器,也可以定时推送数据。

6、支持各种应用层协议
WorkerMan接口上支持各种应用层协议,包括自定义协议。同样GatewayWorker也支持各种应用层协议。

7、多协议支持
有时应用客户端所使用的协议不止一种,例如PC网页客户端使用的是WebSocket协议,而手机App使用的是其它协议。GatewayWorker可以非常方便的支持多协议,只需要以不同的协议开不同的端口即可,业务代码无需改动。

8、支持对象或者资源永久保持
WorkerMan在运行过程中只会载入解析一次PHP文件,然后便常驻内存,这使得类及函数声明、PHP执行环境、符号表等不会重复创建销毁,这与Web容器下运行的PHP机制是完全不同的。在WorkerMan中,一个进程生命周期内静态成员或者全局变量在不主动销毁的情况下是永久保持的,也就是将对象或者链接等资源放到全局变量或者类静态成员中则整个进程生命周期内的所有请求都可以复用。例如只要单个进程内初始化一次数据库连接,则以后这个进程的所有请求都可以复用这个数据库连接,避免了频繁连接数据库过程中TCP三次握手、 数据库权限验证、断开连接时TCP四次握手的过程,极大的提高了应用程序效率。

9、高性能
由于php文件从磁盘读取解析一次后便会常驻内存,下次使用时直接使用内存中的opcode, 极大的减少了磁盘IO及PHP中请求初始化、创建执行环境、词法解析、语法解析、编译opcode、请求关闭等诸多耗时过程, 并且不依赖nginx、apache等容器,少了nginx等容器与PHP通信的开销,最主要的是资源可以永久保持,不必每次初始化数据库连接等等, 所以使用WorkerMan开发应用程序,性能非常高。

10、支持HHVM
支持在HHVM虚拟机上运行,可成倍提升PHP性能。尤其是在cpu密集运算业务中,性能非常优异,是PHP Zend虚拟机8倍左右。通过实际压力测试对比,在没有负载业务的情况下,WorkerMan在HHVM下运行比在Zend PHP5.6运行网络吞吐量提高了30-80%左右

11、方便与其它项目集成
针对其它项目,GatewayWorker提供推送非常简单方便的API,可以在任何项目中使用这个API向所有客户端或者特定客户端推送数据,比如在普通Web项目中推送数据。

12、支持代码热更新
可以reload Worker进程实现业务代码更新升级,而不必担心客户端连接会断开,因为客户端连接都由Gateway进程维持。

13、支持长连接
GatewayWorker主要用于长连接即时通讯应用。如游戏服务器、物联网云服务、IM、移动应用等。

  3. 原理

1、Register、Gateway、BusinessWorker进程启动

2、Gateway、BusinessWorker进程启动后向Register服务进程发起长连接注册自己

3、Register服务收到Gateway的注册后,把所有Gateway的通讯地址保存在内存中

4、Register服务收到BusinessWorker的注册后,把内存中所有的Gateway的通讯地址发给BusinessWorker

5、BusinessWorker进程得到所有的Gateway内部通讯地址后尝试连接Gateway

6、如果运行过程中有新的Gateway服务注册到Register(一般是分布式部署加机器),则将新的Gateway内部通讯地址列表将广播给所有BusinessWorker,BusinessWorker收到后建立连接

7、如果有Gateway下线,则Register服务会收到通知,会将对应的内部通讯地址删除,然后广播新的内部通讯地址列表给所有BusinessWorker,BusinessWorker不再连接下线的Gateway

8、至此Gateway与BusinessWorker通过Register已经建立起长连接

9、客户端的事件及数据全部由Gateway转发给BusinessWorker处理,BusinessWorker默认调用Events.php中的onConnect onMessage onClose处理业务逻辑。

10、BusinessWorker的业务逻辑入口全部在Events.php中,包括onWorkerStart进程启动事件(进程事件)、onConnect连接事件(客户端事件)、onMessage消息事件(客户端事件)、onClose连接关闭事件(客户端事件)、onWorkerStop进程退出事件(进程事件)

二、应用

1. 目录结构

├── Applications // 这里是所有开发者应用项目

│   └── YourApp // 其中一个项目目录,目录名可以自定义

│   ├── Events.php // 开发者只需要关注这个文件

│   ├── start_gateway.php // gateway进程启动脚本,包括端口号等设置

│   ├── start_businessworker.php // businessWorker进程启动脚本

│   └── start_register.php // 注册服务启动脚本

│ ├── start.php // 全局启动脚本,此脚本会依次加载Applications/项目/start_*.php启动脚本 │ └── vendor // GatewayWorker框架和Workerman框架源码目录,此目录开发者不用关心

二、Lib\Gateway类提供的接口
既然(默认)在 Events.php 中处理实际的业务逻辑,回调的事件我们已经知道了。那么怎么向客户端发送消息呢?
命名空间 \GatewayWorker\Lib\Gateway 指向的这个 Gateway 类,提供了一组单发、群发和广播的接口,在 Events.php 中向客户端发信的时候就可以使用这个类。它提供的接口非常丰富:
Gateway::sendToAll($data);      // 向所有客户端发送数据
Gateway::sendToClient($client_id, $data);  // 向某个客户端发送数据
Gateway::closeClient($client_id);      // 关闭某个客户端
Gateway::isOnline($client_id);  // 判断某客户端连接是否在线
Gateway::bindUid($client_id, $uid);    // 绑定 uid 与 client_id
Gateway::unbindUid($client_id, $uid);  // 取消 uid 与 某个 client_id 的绑定
Gateway::isUidOnline($uid);      // 某个 uid 是否在线
Gateway::GetClientIdByUid();     // 获取与 uid 绑定的 client_id 列表(一对多)
Gateway::sendToUid($uid, $data); // 向所有 uid 发送
Gateway::joinGroup($client_id, $group);  // 把该 client_id 加入群组
Gateway::leaveGroup($client_id, $group); // 将 client_id 离开群组
Gateway::sendToGroup($group, $data);     // 向某群组 group 发送
Gateway::getClientCountByGroup($group);  // 获取某个组的在线连接数
Gateway::getClientSessionsByGroup($group); // 获取某个组的连接信息
Gateway::getClientInfoByGroup($group);   // getClientSessionsByGroup 的别名
Gateway::getAllClientCount();     // 获取所有的在线连接数
Gateway::getAllClientSessions();  // 获取所有在线用户的 session
Gateway::getAllClientInfo();      // getAllClientSessions 的别名
Gateway::setSession($client_id, $session);      // 设置 session,原 session 值会被覆盖
Gateway::updateSession($client_id, $session);   // 更新 session,实际上是与旧的session合并
Gateway::getSession($client_id);  // 获取某个 client_id的 session

 三. 实际IM应用

一般来说开发者只需要关注Applications/YourApp/Events.php。因为所有业务代码都在这里开始的。vendor目录为框架目录,开发者不要改动,也不用去理解。

其它start_gateway.php start_businessworker.php start_register.php分别是进程启动脚本,开发者一般不需要改动这三个文件。三个脚本统一由根目录的start.php启动。

Events.php
例如下面是一个聊天室示例

<?php
use \GatewayWorker\Lib\Gateway;
class Events
{/*** 当客户端连接时触发* 如果业务不需此回调可以删除onConnect* @param int $client_id 连接id*/public static function onConnect($client_id){// 向当前client_id发送数据Gateway::sendToClient($client_id, "Hello $client_id");// 向所有人发送Gateway::sendToAll("$client_id login");}/*** 当客户端发来消息时触发* @param int $client_id 连接id* @param string $message 具体消息*/public static function onMessage($client_id, $message){// 向所有人发送Gateway::sendToAll("$client_id said $message");}/*** 当用户断开连接时触发* @param int $client_id 连接id*/public static function onClose($client_id){// 向所有人发送GateWay::sendToAll("$client_id logout");}
}


Events.php中定义5个事件回调方法,

onWorkerStart businessWorker进程启动事件(一般用不到)
onConnect 连接事件(比较少用到)
onMessage 消息事件(必用)
onClose 连接断开事件(比较常用到)
onWorkerStop businessWorker进程退出事件(几乎用不到)
5个回调接口说明参见 Events类的回调接口 一节

其中消息事件onMessage是必须的,其它事件回调可以不实现。

<?php
use \GatewayWorker\Lib\Gateway;
class Events
{/*** 当客户端发来消息时触发* @param int $client_id 连接id* @param string $message 具体消息*/public static function onMessage($client_id, $message){// 向所有人发送Gateway::sendToAll("$client_id said $message");}
}


start_gateway.php
start_gateway.php为gateway进程启动脚本,主要定义了客户端连接的端口号、协议等信息,具体参见 Gateway类的使用一节。

客户端连接的就是start_gateway.php中初始化的Gateway端口。

start_businessworker.php
start_businessworker.php为businessWorker进程启动脚本,也即是调用Events.php的业务处理进程,具体参见 BusinessWorker类的使用一节。

start_register.php
start_register.php为注册服务启动脚本,用于协调GatewayWorker集群内部Gateway与Worker的通信,参见Register类使用一节。

这篇关于GatewayWorker框架的详解和应用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1138311

相关文章

CSS3 布局样式及其应用举例

《CSS3布局样式及其应用举例》CSS3的布局特性为前端开发者提供了无限可能,无论是Flexbox的一维布局还是Grid的二维布局,它们都能够帮助开发者以更清晰、简洁的方式实现复杂的网页布局,本文给... 目录深入探讨 css3 布局样式及其应用引言一、CSS布局的历史与发展1.1 早期布局的局限性1.2

C#特性(Attributes)和反射(Reflection)详解

《C#特性(Attributes)和反射(Reflection)详解》:本文主要介绍C#特性(Attributes)和反射(Reflection),具有很好的参考价值,希望对大家有所帮助,如有错误... 目录特性特性的定义概念目的反射定义概念目的反射的主要功能包括使用反射的基本步骤特性和反射的关系总结特性

详解如何在SpringBoot控制器中处理用户数据

《详解如何在SpringBoot控制器中处理用户数据》在SpringBoot应用开发中,控制器(Controller)扮演着至关重要的角色,它负责接收用户请求、处理数据并返回响应,本文将深入浅出地讲解... 目录一、获取请求参数1.1 获取查询参数1.2 获取路径参数二、处理表单提交2.1 处理表单数据三、

PyQt6中QMainWindow组件的使用详解

《PyQt6中QMainWindow组件的使用详解》QMainWindow是PyQt6中用于构建桌面应用程序的基础组件,本文主要介绍了PyQt6中QMainWindow组件的使用,具有一定的参考价值,... 目录1. QMainWindow 组php件概述2. 使用 QMainWindow3. QMainW

MySQL中SQL的执行顺序详解

《MySQL中SQL的执行顺序详解》:本文主要介绍MySQL中SQL的执行顺序,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录mysql中SQL的执行顺序SQL执行顺序MySQL的执行顺序SELECT语句定义SELECT语句执行顺序总结MySQL中SQL的执行顺序

Java资源管理和引用体系的使用详解

《Java资源管理和引用体系的使用详解》:本文主要介绍Java资源管理和引用体系的使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、Java的引用体系1、强引用 (Strong Reference)2、软引用 (Soft Reference)3、弱引用 (W

C语言中的常见进制转换详解(从二进制到十六进制)

《C语言中的常见进制转换详解(从二进制到十六进制)》进制转换是计算机编程中的一个常见任务,特别是在处理低级别的数据操作时,C语言作为一门底层编程语言,在进制转换方面提供了灵活的操作方式,今天,我们将深... 目录1、进制基础2、C语言中的进制转换2.1 从十进制转换为其他进制十进制转二进制十进制转八进制十进

MySQL中的两阶段提交详解(2PC)

《MySQL中的两阶段提交详解(2PC)》:本文主要介绍MySQL中的两阶段提交(2PC),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录引言两阶段提交过程sync_binlog配置innodb_flush_log_at_trx_commit配置总结引言在Inn

Python MCPInspector调试思路详解

《PythonMCPInspector调试思路详解》:本文主要介绍PythonMCPInspector调试思路详解,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋... 目录python-MCPInspector调试1-核心知识点2-思路整理1-核心思路2-核心代码3-参考网址

Java Jackson核心注解使用详解

《JavaJackson核心注解使用详解》:本文主要介绍JavaJackson核心注解的使用,​​Jackson核心注解​​用于控制Java对象与JSON之间的序列化、反序列化行为,简化字段映射... 目录前言一、@jsonProperty-指定JSON字段名二、@JsonIgnore-忽略字段三、@Jso