{"id":15014319,"url":"https://github.com/daoshenzzg/socket-mqtt","last_synced_at":"2025-04-13T02:20:00.111Z","repository":{"id":41262832,"uuid":"172690832","full_name":"daoshenzzg/socket-mqtt","owner":"daoshenzzg","description":"基于Netty+MQTT的高性能推送服务框架。支持普通Socket、MQTT、MQTT web socket协议。非常方便接入上层业务实现推送业务。","archived":false,"fork":false,"pushed_at":"2023-11-30T01:06:38.000Z","size":1799,"stargazers_count":620,"open_issues_count":0,"forks_count":254,"subscribers_count":27,"default_branch":"master","last_synced_at":"2025-04-04T04:12:00.590Z","etag":null,"topics":["iot","java","mqtt","netty","rpc","socket","websocket"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/daoshenzzg.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2019-02-26T10:35:21.000Z","updated_at":"2025-03-26T03:17:53.000Z","dependencies_parsed_at":"2022-07-13T15:29:35.153Z","dependency_job_id":"6138083c-e508-493e-8b51-0b6a1bc50c76","html_url":"https://github.com/daoshenzzg/socket-mqtt","commit_stats":{"total_commits":64,"total_committers":3,"mean_commits":"21.333333333333332","dds":0.390625,"last_synced_commit":"6e46f0a38f2ffbb59dd1636443a41639aae50de0"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/daoshenzzg%2Fsocket-mqtt","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/daoshenzzg%2Fsocket-mqtt/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/daoshenzzg%2Fsocket-mqtt/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/daoshenzzg%2Fsocket-mqtt/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/daoshenzzg","download_url":"https://codeload.github.com/daoshenzzg/socket-mqtt/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248654543,"owners_count":21140319,"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":["iot","java","mqtt","netty","rpc","socket","websocket"],"created_at":"2024-09-24T19:45:28.080Z","updated_at":"2025-04-13T02:20:00.085Z","avatar_url":"https://github.com/daoshenzzg.png","language":"Java","funding_links":[],"categories":["网络编程"],"sub_categories":[],"readme":"\u003ca href=\"https://996.icu\"\u003e![](https://img.shields.io/badge/link-996.icu-red.svg)\u003c/a\u003e\n\n# socket-mqtt: Netty4.x + MQTT\n\n这是一个基于[Netty4.x](https://netty.io/) + [MQTT](http://mqtt.org/)实现的Push推送基础框架。相比于原生Netty，  \nsocket-mqtt：\n\n- 为C/S模式开发封装简单统一的编程模式\n- 简单高性能的代码\n- 统一的连接管理方案\n- 统一的线程管理方案\n- 网络基础问题的解决与支持：如心跳保持、压缩解压缩、编码与解码、加密与解密等\n- 各种网络参数、连接池实现、监听器实现等可配置可替换\n- 可实现对等集群（见[负载均衡方案](LOAD_BALANCE.md)）\n- 提供数据统计/监控组件\n- 支持普通socket、MQTT、MQTT web socket协议及[自定义协议](src/main/java/com/yb/socket/pojo/protocol/README.md)\n\n# 项目结构\n\n- codec: 封装编码与解码\n- compression: 封装压缩与解压缩\n- count: 封装统计信息\n- database: 基于hsql的内存数据库\n- encrypt: 封装加密与解密\n- future: 封装同步和异步调用\n- listener: 封装事件监听，包括消息、通道、异常三类事件监听器\n- service: 封装C/S模型、通道、心跳管理、消息分发等核心模块\n\n# Linux内核参数配置\n\n```\n# 允许回收TCP连接  \nnet.ipv4.tcp_tw_reuse = 0  \nnet.ipv4.tcp_tw_recycle = 0  \n\n# TCP 缓冲区内存  \nnet.ipv4.tcp_rmem = 4096 87380 8388608  \nnet.ipv4.tcp_wmem = 4096 87380 8388608  \nnet.ipv4.tcp_mem = 94500000 915000000 927000000    \n# ulimits 优化  \nfs.file-max = 1065353  \nkernel.pid_max = 65536  \n*  soft      nofile 655360  *  hard      nofile 655360  \n```\n\n# 压测报告\n\n**MQTT协议-上下行消息处理能力压测**\n\u003e 单Broker8核16G，支持44万连接（进程启动内存5G、开启心跳）；1万客户端 单消息1024B 下行tps: 16万+； 4000客户端 Publish 单消息1024B 上行tps: 17万+，千兆网卡流量基本打满。\n\n**自定义协议-单机连接数支撑能力压测**\n\n\u003e 单Broker8核16G开启心跳机制，客户端每30秒发送一次心跳，支持65万连接，稳定运行10分钟后，系统负载不到2个，服务端毫无压力。由于测试资源限制，理论上可以支持百万连接。\n\n\n\n#### MQTT协议-消息下行能力\n\n\u003ctable\u003e  \n    \u003ctr\u003e  \n        \u003cth\u003e1万Clients订阅的消息下行能力\u003c/th\u003e  \n        \u003cth\u003e对应下行负载情况\u003c/th\u003e  \n    \u003ctr\u003e  \n        \u003ctd width=\"50%\"\u003e  \n            \u003cimg src=\"doc/sub.png\"\u003e  \n        \u003c/td\u003e  \n        \u003ctd width=\"50%\"\u003e  \n            \u003cimg src=\"doc/dstat_sub.png\"\u003e  \n        \u003c/td\u003e  \n    \u003c/tr\u003e  \n\u003c/table\u003e\n\n#### MQTT协议-消息上行能力\n\n\u003ctable\u003e  \n    \u003ctr\u003e  \n        \u003cth\u003e4000Clients订阅消息上行能力\u003c/th\u003e  \n        \u003cth\u003e对应上行负载情况\u003c/th\u003e  \n    \u003ctr\u003e  \n        \u003ctd width=\"50%\"\u003e  \n            \u003cimg src=\"doc/pub.png\"\u003e  \n        \u003c/td\u003e  \n        \u003ctd width=\"50%\"\u003e  \n            \u003cimg src=\"doc/dstat_pub.png\"\u003e  \n        \u003c/td\u003e  \n    \u003c/tr\u003e  \n\u003c/table\u003e\n\n#### MQTT协议-查看连接数情况\n\n\u003ctable\u003e  \n    \u003ctr\u003e  \n        \u003cth\u003e查看连接数(telnet 10.43.204.61 8001; get status)\u003c/th\u003e  \n        \u003cth\u003e查看连接数(ss -l)\u003c/th\u003e  \n    \u003ctr\u003e  \n        \u003ctd width=\"50%\"\u003e  \n            \u003cimg src=\"doc/status.png\"\u003e  \n        \u003c/td\u003e  \n        \u003ctd width=\"50%\"\u003e  \n            \u003cimg src=\"doc/ss.png\"\u003e  \n        \u003c/td\u003e  \n    \u003c/tr\u003e  \n\u003c/table\u003e\n\n# 使用说明\n\n各种测试类的源码在src/test/java/com/yb/socket包路径下:  \n包括:\n\n- 普通socket Server/Client\n- MQTT socket Server/Client\n- 带注册中心的普通socket/MQTT socket\n- 基于内存数据库的模拟订阅推送\n- 自定义协议 Server/Client\n\n## 服务启动配置选项\n\n```java\nServer server = new Server();  \n// 设置Broker端口  \nserver.setPort(8000); // 设置启动信息统计。默认true  \nserver.setOpenCount(true);  \n// 设置启用心跳功能。默认true  \nserver.setCheckHeartbeat(true);  \n// 设置启动服务状态，默认端口8001。通过telnet server_ip 8001; get status查看服务信息  \nserver.setOpenStatus(true);  \n// 服务状态端口。默认8001  \nserver.setStatusPort(8001);  \n// 设置服务名称  \nserver.setServiceName(\"Demo\");  \n// 设置工作线程数量。默认CPU个数+1  \nserver.setWorkerCount(64);  \n// 是否开户业务处理线程池。默认false  \nserver.setOpenExecutor(true);  \n// 设置tcp no delay。默认true  \nserver.setTcpNoDelay(true);  \n// 是否启用keepAlive。默认true  \nserver.setKeepAlive(true);  \n// 自定义监听器，可处理相关事件  \nserver.addEventListener(new EchoMessageEventListener());  \n// 设置Broker启动协议。SocketType.MQTT - MQTT协议； SocketType.NORMAL - 普通Socket协议；SocketType.MQTT_WS - MQTT web socket协议；  \nserver.setSocketType(SocketType.MQTT);  \n// 绑定端口启动服务  \nserver.bind();  \n```\n\n## MQTT web socket server DEMO\n\n```java\nServer server = new Server();  \nserver.setPort(8000);  \nserver.addEventListener(new EchoMessageEventListener());  \nserver.setSocketType(SocketType.MQTT_WS);  \nserver.bind();  \n\n//模拟推送  \nString message = \"this is a web socket message!\";  \nMqttRequest mqttRequest = new MqttRequest((message.getBytes()));  \nwhile (true) {  \n    if (server.getChannels().size() \u003e 0) { \n        logger.info(\"模拟推送消息\");     \n        for (WrappedChannel channel : server.getChannels().values()) {  \n            server.send(channel, \"yb/notice/\", mqttRequest);     \n        }\n    } \n    Thread.sleep(1000L);\n}  \n```\n\n## MQTT web socket client(浏览器)\n\n```\n可用在线mqtt测试：http://www.tongxinmao.com/txm/webmqtt.php  \nTopic  Payload    Time   QoS  \nyb/notice/ this is a web socket message!  2019-2-27 16:54:54 0  \n```\n\n## Normal socket server DEMO\n\n```java\nServer server = new Server();  \nserver.setPort(8000);  \nserver.addEventListener(new JsonEchoMessageEventListener());  \nserver.addChannelHandler(\"decoder\", JsonDecoder::new);  \nserver.addChannelHandler(\"encoder\", JsonEncoder::new);  \nserver.bind();  \n\n//模拟推送  \nJSONObject message = new JSONObject();  \nmessage.put(\"action\", \"echo\");  \nmessage.put(\"message\", \"this is a normal socket message!\");  \n\nRequest request = new Request();  \nrequest.setSequence(0);  \nrequest.setMessage(message);  \nwhile (true) {  \n    if (server.getChannels().size() \u003e 0) {  \n        logger.info(\"模拟推送消息\");     \n        for (WrappedChannel channel : server.getChannels().values()) {\n            channel.send(request);\n            Thread.sleep(5000L);\n        }\n    }\n}  \n```\n\n## Normal socket client DEMO\n\n```java\nClient client = new Client();  \nclient.setIp(\"127.0.0.1\");  \nclient.setPort(8000);  \nclient.setConnectTimeout(10000);  \nclient.addChannelHandler(\"decoder\", JsonDecoder::new);  \nclient.addChannelHandler(\"encoder\", JsonEncoder::new);  \nclient.connect();  \n\nfor (int i = 0; i \u003c 2; i++) {  \n    JSONObject message = new JSONObject();   \n    message.put(\"action\", \"echo\"); \n    message.put(\"message\", \"hello world!\");  \n    Request request = new Request();  \n    request.setSequence(i); \n    request.setMessage(message);\n    Response response = (Response) \n    client.sendWithSync(request, 3000);  \n    logger.info(\"成功接收到同步的返回: '{}'.\", response);\n}  \n\nclient.shutdown();  \n```\n\n## 带注册中心 center DEMO\n\n```java\nServer server = new Server();  \nserver.setPort(9000);  \nserver.setCheckHeartbeat(false);  \nserver.addChannelHandler(\"decoder\", JsonDecoder::new);  \nserver.addChannelHandler(\"encoder\", JsonEncoder::new);  \nserver.addEventListener(new com.yb.socket.center.CenterMockMessageEventListener());  \nserver.bind();  \n```\n\n## 带注册中心 server DEMO\n\n```java\nServer server = new Server();  \nserver.setPort(8000);  \nserver.setCheckHeartbeat(false);  \nserver.setCenterAddr(\"127.0.0.1:9000,127.0.0.1:9010\");  \nserver.addEventListener(new JsonEchoMessageEventListener());  \nserver.bind();  \n```\n\n## 带注册中心 client DEMO\n\n```java\nClient client = new Client();  \nclient.setCheckHeartbeat(false);  \nclient.setCenterAddr(\"127.0.0.1:9000,127.0.0.1:9010\");  \nclient.addChannelHandler(\"decoder\", JsonDecoder::new);  \nclient.addChannelHandler(\"encoder\", JsonEncoder::new);  \nclient.connect();  \n\nJSONObject message = new JSONObject();  \nmessage.put(\"action\", \"echo\");  \nmessage.put(\"message\", \"hello\");  \n\nfor (int i = 0; i \u003c 5; i++) {  \n    Request request = new Request();  \n    request.setSequence(i);\n    request.setMessage(message);\n    client.send(request);\n    Thread.sleep(5000L);\n}  \n```\n\n# 后续规划\n\n- 支持MQTT主题过滤机制\n- 支持SSL连接方式\n- 完整的QoS服务质量等级实现DEMO\n- 遗嘱消息, 保留消息及消息分发重试\n\n# 压测工具\n\n- https://github.com/daoshenzzg/mqtt-mock\n\n# 参考项目\n\n- https://github.com/netty/netty\n- https://github.com/1ssqq1lxr/iot_push\n- https://github.com/Wizzercn/MqttWk\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdaoshenzzg%2Fsocket-mqtt","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdaoshenzzg%2Fsocket-mqtt","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdaoshenzzg%2Fsocket-mqtt/lists"}