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

相关文章

sky-take-out项目中Redis的使用示例详解

《sky-take-out项目中Redis的使用示例详解》SpringCache是Spring的缓存抽象层,通过注解简化缓存管理,支持Redis等提供者,适用于方法结果缓存、更新和删除操作,但无法实现... 目录Spring Cache主要特性核心注解1.@Cacheable2.@CachePut3.@Ca

深入浅出Spring中的@Autowired自动注入的工作原理及实践应用

《深入浅出Spring中的@Autowired自动注入的工作原理及实践应用》在Spring框架的学习旅程中,@Autowired无疑是一个高频出现却又让初学者头疼的注解,它看似简单,却蕴含着Sprin... 目录深入浅出Spring中的@Autowired:自动注入的奥秘什么是依赖注入?@Autowired

SpringBoot请求参数传递与接收示例详解

《SpringBoot请求参数传递与接收示例详解》本文给大家介绍SpringBoot请求参数传递与接收示例详解,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋... 目录I. 基础参数传递i.查询参数(Query Parameters)ii.路径参数(Path Va

GSON框架下将百度天气JSON数据转JavaBean

《GSON框架下将百度天气JSON数据转JavaBean》这篇文章主要为大家详细介绍了如何在GSON框架下实现将百度天气JSON数据转JavaBean,文中的示例代码讲解详细,感兴趣的小伙伴可以了解下... 目录前言一、百度天气jsON1、请求参数2、返回参数3、属性映射二、GSON属性映射实战1、类对象映

RabbitMQ 延时队列插件安装与使用示例详解(基于 Delayed Message Plugin)

《RabbitMQ延时队列插件安装与使用示例详解(基于DelayedMessagePlugin)》本文详解RabbitMQ通过安装rabbitmq_delayed_message_exchan... 目录 一、什么是 RabbitMQ 延时队列? 二、安装前准备✅ RabbitMQ 环境要求 三、安装延时队

从基础到高级详解Python数值格式化输出的完全指南

《从基础到高级详解Python数值格式化输出的完全指南》在数据分析、金融计算和科学报告领域,数值格式化是提升可读性和专业性的关键技术,本文将深入解析Python中数值格式化输出的相关方法,感兴趣的小伙... 目录引言:数值格式化的核心价值一、基础格式化方法1.1 三种核心格式化方式对比1.2 基础格式化示例

Java中的stream流分组示例详解

《Java中的stream流分组示例详解》Java8StreamAPI以函数式风格处理集合数据,支持分组、统计等操作,可按单/多字段分组,使用String、Map.Entry或Java16record... 目录什么是stream流1、根据某个字段分组2、按多个字段分组(组合分组)1、方法一:使用 Stri

Spring创建Bean的八种主要方式详解

《Spring创建Bean的八种主要方式详解》Spring(尤其是SpringBoot)提供了多种方式来让容器创建和管理Bean,@Component、@Configuration+@Bean、@En... 目录引言一、Spring 创建 Bean 的 8 种主要方式1. @Component 及其衍生注解

PostgreSQL简介及实战应用

《PostgreSQL简介及实战应用》PostgreSQL是一种功能强大的开源关系型数据库管理系统,以其稳定性、高性能、扩展性和复杂查询能力在众多项目中得到广泛应用,本文将从基础概念讲起,逐步深入到高... 目录前言1. PostgreSQL基础1.1 PostgreSQL简介1.2 基础语法1.3 数据库

Python异步编程之await与asyncio基本用法详解

《Python异步编程之await与asyncio基本用法详解》在Python中,await和asyncio是异步编程的核心工具,用于高效处理I/O密集型任务(如网络请求、文件读写、数据库操作等),接... 目录一、核心概念二、使用场景三、基本用法1. 定义协程2. 运行协程3. 并发执行多个任务四、关键