{"id":14989550,"url":"https://github.com/liutian/light-push","last_synced_at":"2025-06-22T01:34:09.765Z","repository":{"id":74206853,"uuid":"94174298","full_name":"liutian/light-push","owner":"liutian","description":"轻量级推送服务和实时在线监控平台，同时用于开发即时通信系统，基于node的socket.io，支持web、android、ios客户端，支持移动端离线推送，可进行分布式部署","archived":false,"fork":false,"pushed_at":"2025-04-09T13:38:56.000Z","size":22659,"stargazers_count":143,"open_issues_count":1,"forks_count":33,"subscribers_count":10,"default_branch":"master","last_synced_at":"2025-05-24T19:05:15.513Z","etag":null,"topics":["apns","docker","im","koa2","material","material-design","nginx","node","node-socket","pm2","push","redis","socket-io","websocket","yaml"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/liutian.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2017-06-13T05:50:24.000Z","updated_at":"2024-10-24T07:31:34.000Z","dependencies_parsed_at":"2025-04-12T00:51:34.259Z","dependency_job_id":"2c2d654d-4d6c-4517-86bf-6a9c732c0348","html_url":"https://github.com/liutian/light-push","commit_stats":{"total_commits":172,"total_committers":4,"mean_commits":43.0,"dds":0.5523255813953488,"last_synced_commit":"7ddfa44899da376646c7a8c2367e4a892b630d42"},"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/liutian/light-push","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/liutian%2Flight-push","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/liutian%2Flight-push/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/liutian%2Flight-push/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/liutian%2Flight-push/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/liutian","download_url":"https://codeload.github.com/liutian/light-push/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/liutian%2Flight-push/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261220293,"owners_count":23126726,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["apns","docker","im","koa2","material","material-design","nginx","node","node-socket","pm2","push","redis","socket-io","websocket","yaml"],"created_at":"2024-09-24T14:18:33.162Z","updated_at":"2025-06-22T01:34:04.750Z","avatar_url":"https://github.com/liutian.png","language":"JavaScript","readme":"### 概述\n轻量级推送服务和实时在线监控平台，同时用于开发即时通信系统，基于node的socket.io，支持web、android、ios客户端，支持移动端离线推送，可进行分布式部署\n\n### 前言\n随着互联网网速的不断提升，即时消息通信的应用场景越来越多。我在参与公司多个产品的研发中，不止一次的遇到需要集成聊天功能的需求。既然是聊天就必须把消息尽快送达目标用户，做的多了就有了一套自己的经验和想法，然后借着闲暇时间一点点的就写出了这个项目。这个项目灵感来源于实际开发工作，同时又把它应用到自己的工作中。希望它能帮到你，也希望你能给我更多的反馈和改进意见，让它帮助更多的人。\n\n![img](https://github.com/liutian/light-push/raw/master/assets/demo.gif)\n\n\n### 系统概要和功能特性\n- 业务系统通过`RESTful`接口方式调用推送服务\n- 客户端通过`socket.io`协议与推送服务建立连接\n- 通过命名空间对客户端进行安全隔离和管理，不同客户端之间不能相互收发消息，如果业务系统是saas模式，命名空间相当于公司或组织的概念\n- 使用负载均衡器来负责每一个客户端的接入工作，每一个客户端随机分配给一个推送服务的后端节点，保证推送服务的负载更加平均(负载均衡器指类似nginx的服务)\n- 单个客户端和推送服务建立强关联，即一旦客户端与推送服务的某个节点建立连接，除非客户端下线否则所有数据处理和操作都有该节点完成，同时保证会话信息不丢失，可实现多机多进程部署\n- 使用`redis`保存系统运行时所需的数据，保证系统响应速度\n- 可实现单个用户多端连接，满足聊天系统多端登陆需求，同时接收消息，每一个客户端至少有一个默认房间，房间名: `user_ + userid`\n- 通过界面UI或者接口来监控，统计客户端在线信息\n- 通过界面UI模拟客户端上线/下线\n- 通过界面UI模拟推送功能\n- 模拟网络异常下推送服务已经推送消息但是客户端无法接收的情况，方便客户端编写数据同步功能\n- 通过界面UI或者接口统计消息到达率(需要客户端ack确认回执)\n- 可查询历史消息，可统计每天的推送总量，以及当前小时/当前分钟的推送总量\n- 当客户端未收到推送消息时，如果客户端为`ios`平台则用`apns`做离线推送，如果是`android`会保存该消息直到客户端上线\n- 监听每一个客户端接入事件并可回调业务系统，由业务系统决定客户端是否有权接入\n- 监听每一个用户的离线事件并可回调业务系统\n- 客户端房间变动事件可选择性的广播推送到对应的房间中\n- 客户端可主动推送消息，满足聊天系统中正在输入中的功能需求（正常情况的推送应有业务系统发起，保障推送服务的安全和稳定）\n- 可为每一个客户端保存一些特殊数据，比如最后一次的接入信息，客户端操作系统信息等等，同时提供一键清除僵尸客户端功能(一定时间未接入过推送服务器)\n- 推送服务本身支持cors跨域访问，方便基于推送服务来开发管理界面\n- 采用消息队列方式推送离线消息，保证系统在高并发下的稳定性\n- 服务运行时的各个参数可自行配置，比如消息默认失效时间等\n\n### 快速体验\n- `sudo docker run -id -p 443:443 -p 80:80 --name light-push-demo liuss/light-push:1.2.0 /mnt/data/start.sh`\n- 访问管理页面: `https://127.0.0.1/push-admin` 登录名 admin 密码 123456\n\n### 客户端调用(web)\n```\n// demo为命名空间；uuid为客户端唯一标示；userid为客户端所属的用户ID\nlet socket = io.connect('https://127.0.0.1:55555/demo?uuid=' + uuid + '\u0026userid=' + userid, {\n  path: '/push/socket.io/'\n});\n\nsocket.on('connect', function () {\n  // 客户端主动加入房间\n  socket.emit('joinRoom', ['room1'], function (result) {\n    console.log('joinRoom:' + JSON.stringify(result));\n  });\n\n  // 接收服务器端的推送消息\n  socket.on('push', function (data) {\n    console.log('push:' + JSON.stringify(data));\n    // 消息确认回执\n    socket.emit('ackPush', { id: data.id });\n  });\n\n  // 客户端主动离开房间\n  socket.emit('leaveRoom', ['room2'], function (result) {\n    console.log('leaveRoom:' + JSON.stringify(result));\n  });\n});\n```\n\n\n### 环境搭建\n- 安装 `nodejs` (需要超级管理员权限) [详情](https://nodejs.org/en/download/package-manager/#freebsd-and-openbsd)\n```\ncurl --silent --location https://rpm.nodesource.com/setup_10.x | sudo bash -\nsudo yum install -y nodejs\n```\n- 安装pm2，如果安装中报错或者长时间没有响应 尝试通过第三方镜像安装 例如： `npm install -g pm2 --registry=https://registry.npm.taobao.org`\n```\nsudo npm install -g pm2\n```\n- 安装redis 5.0 以上版本 [官网](http://redis.io/download) [安装步骤](http://blog.csdn.net/zhenzhendeblog/article/details/52161515)\n\u003e`src/config.yaml` 中的 `redis_address` 用来配置redis服务器地址 ， 如果redis是集群模式，则将该配置改为数组类型\n- 安装nginx集群部署时需要，[yum源](http://nginx.org/en/linux_packages.html#RHEL-CentOS)\n```\nyum install nginx\n```\n- 系统初始化之后，需要调用 `/api/admin/namespace/save` 接口来生成一个命名空间，客户端通过这个命名空间连接服务器；每个客户的必须有一个所属的命名空间才能连接服务器，否则服务器会拒绝客户端的所有请求\n\n- 集群部署`nginx`方案，请参考 `doc/nginx.conf` ；`redis`配置,请参考 `doc/redis.conf`；`node`单机集群`pm2`方案配置，请参考`app.json`，[pm2使用说明](https://github.com/Unitech/pm2)\n\n- 通过`node`命令启动服务，则端口配置见 `src/config.yaml` ， `connector_port` : 连接服务器； `logic_port` : 接口服务器；如果通过`pm2`方式启动，则`app.json` 中 `args` 有 `-p` 参数，则会覆盖 `src/config.yaml` 中端口配置\n\n### 性能调优\n详情见 `doc/performance.md`\n\n### 客户端模拟测试\n- 执行测试：`nohup node --max-old-space-size=3000 simulator.js \u003e\u003e test1.log 2\u003e\u00261 \u0026`\n- 根据具体情况调整 `test/simulator.yaml` 测试配置，主要调整的参数：server，push_option_path，client_namespace，client_total，client_uuid_init\n- 配置参数 `client_uuid_init` 需要在每次启动测试实例时手动修改，一般为现有在线客户端数 + `client_total`\n- 开始测试之前需要手动修改 `/etc/sysctl.conf` ,增加如下配置\n  ```\n  fs.file-max=100000\n  fs.nr_open=100000\n  net.ipv4.ip_local_port_range=1024 65000\n  ```\n- 在推出测试终端时必须通过 `exit` 命令退出，否则后台测试进程会被系统kill\n\n### 并发测试\n- 安装测试工具 `yum install httpd-tools -y`\n- 执行测试见 `test/ab.txt`\n- 根据情况修改测试请求内容 `test/ab_post`\n\n### 其他\n\n\u003e 接口说明和注意事项见[wiki](https://github.com/liutian/light-push/wiki)\n\n\u003e 推送服务控制台项目 [地址](https://github.com/liutian/light-push-admin)\n\n\u003e 配套ios [演示项目](https://github.com/visionetwsk/WSK_iOS_SDK_Demo) [SDK](https://github.com/visionetwsk/WSK_iOS_SDK)\n\n\u003e 配套android [SDK](https://bintray.com/visionetwsk/wskcss/wsk_sdk/1.1.1)\n\n\u003e QQ技术交流群 [643889498](https://jq.qq.com/?_wv=1027\u0026k=5WHk8ay)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fliutian%2Flight-push","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fliutian%2Flight-push","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fliutian%2Flight-push/lists"}