{"id":19885246,"url":"https://github.com/dinstone/focus","last_synced_at":"2025-05-02T16:31:41.121Z","repository":{"id":37860894,"uuid":"209948208","full_name":"dinstone/focus","owner":"dinstone","description":"Focus is a cross language lightweight RPC framework that originated from JRPC.","archived":false,"fork":false,"pushed_at":"2024-12-24T01:57:37.000Z","size":1401,"stargazers_count":4,"open_issues_count":1,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-07T03:25:32.339Z","etag":null,"topics":["json","microservice","netty","protobuf","rpc"],"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/dinstone.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,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-09-21T08:09:02.000Z","updated_at":"2024-12-24T01:57:41.000Z","dependencies_parsed_at":"2024-01-06T14:30:10.089Z","dependency_job_id":"d2b21f2b-7962-4085-ab76-5b38f6e90655","html_url":"https://github.com/dinstone/focus","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dinstone%2Ffocus","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dinstone%2Ffocus/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dinstone%2Ffocus/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dinstone%2Ffocus/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dinstone","download_url":"https://codeload.github.com/dinstone/focus/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252071811,"owners_count":21690095,"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":["json","microservice","netty","protobuf","rpc"],"created_at":"2024-11-12T17:33:42.919Z","updated_at":"2025-05-02T16:31:41.097Z","avatar_url":"https://github.com/dinstone.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Overview\n\n[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://github.com/dinstone/focus/blob/master/LICENSE)\n[![Maven Central](https://img.shields.io/maven-central/v/com.dinstone.focus/focus-parent.svg?label=Maven%20Central)](https://search.maven.org/search?q=com.dinstone.focus)\n\n**Focus RPC** is the next generation cross language lightweight RPC framework. It can quickly and easily develop microservice applications, which greatly simplifies RPC programming.\n\n**Focus RPC** 是下一代跨平台、跨语言的轻量级RPC框架。旨在帮助开发者可以更加高效地构建和维护微服务应用程序。他们可以利用统一的接口和协议，在不同的平台和语言之间进行通信和协作，从而提高开发效率和系统可靠性，简化多平台下的RPC编程，可以很轻松地实现云端编程和移动端编程。\n\n- [focus-go](https://github.com/focus-rpc/focus-go) is the go language implementation of the Focus.\n- [focus-java](https://github.com/focus-rpc/focus-java) is the java language implementation of the Focus.\n\n---\n\n# Focus Java Implementation\n\n通常，评价一个 RPC 框架是否优秀、高效能，有 3 个基本标准：\n\n* 简单易用，无侵入：不需要过多的研究使用文档，查看快速开始或 API 就能快速用起来，框架代码无需侵入业务代码就能完成调用。\n\n* 抽象适度，可扩展：框架分层耦合合理、模块职责内聚、实现简洁易懂，能覆盖绝大多数场景，对特殊场景可通过设置或扩展来满足需求。\n\n* 性能优越，可演进：“高性能”永远是一个绕不开的关注点，框架的实现也是编码能力的体现，保持 API 不变，但实现可持续迭代改进。\n\n[focus-java](https://github.com/focus-rpc/focus-java) 框架在高效能方面做了很多的努力，贯彻最小侵入性设计理念，坚持面向对象的SOLID原则，追求极简协议和代码简洁，能够让开发者和企业更轻松地集成和使用RPC框架。\n\n对于希望使用和学习RPC框架的同学来说，选择一个高效、易用、灵活和可扩展的框架非常重要。Focus框架可以为他们提供更多的参考和选择，帮助他们更好地了解和掌握RPC框架的使用技巧和最佳实践。\n\n## Features\n\n* 跨语言支持。同时支持多种串行化协议：Jackson和Protobuff。\n* 模块化API。模块化的客户端和服务端API，可扩展的系统架构核心小于1 MB。\n* 分层架构。合理严谨的分层（包括API层、代理层、调用层、协议层、传输层）使得依赖最小化、可控，适用于更多运行环境。\n* 可插拔的服务发现机制。支持 Consul，Nacos，Polaris等常见注册中心。\n* 可插拔的调用拦截机制。可实现Logging、Tracing、Metrics、限流、熔断等服务安全、可观测性、服务治理功能。\n* 支持同步调用、异步调用、泛化调用。满足各种场景下的不同诉求。\n* 高效的自定义协议。二进制消息交换协议[Photon](https://github.com/dinstone/photon)和[Focus](https://github.com/dinstone/focus)的RPC协议。\n* 不同级别的服务控制。全局级别、服务级别的序列化、压缩、超时、重试设置，方法级别的超时、重试设置。\n* Spring boot 集成支持友好。简化Spring应用的集成、开发难度。\n\n### Design Idea\n\n* Modular client and server APIs, scalable system architecture, and framework core less than 1 MB in size.\n* Support a variety of serialization protocol at the same time - Jackson、Protobuff、Protostuff\n* Layered architecture, including API layer, Proxy layer, Invoke layer, Protocol layer, Transport layer\n* Pluggable invoke interception mechanism, that facilitates extensions such as service security, observability, and service governance.\n\n### Ease of use\n\n* Out of the box client-side and server-side API\n* Spring boot starter integration friendly\n* Support synchronous, asynchronous and generalized calls\n\n### Performance\n\n* Efficient custom protocol ([Photon](https://github.com/dinstone/photon) message exchange protocol and Focus RPC protocol)\n* High-performance NIO socket framework support - Netty4\n\n## Quick Start\n\nThe quick start gives a basic example of running client and server on the same machine. For more advanced examples, please refer to the example project : [focus-examples](https://github.com/dinstone/focus-examples). For the detailed information about using and developing Focus, please jump to [Documents](#documents).\n\n\u003e The minimum requirements to run the quick start are:\n\u003e\n\u003e - JDK 1.8 or above\n\u003e - A java-based project management software like [Maven](maven) or [Gradle](gradle)\n\n### Synchronous calls\n\n1. create maven project focus-quickstart and add dependencies to pom.\n\n```xml\n\u003cdependencies\u003e\n    \u003cdependency\u003e\n        \u003cgroupId\u003ecom.dinstone.focus\u003c/groupId\u003e\n        \u003cartifactId\u003efocus-server-photon\u003c/artifactId\u003e\n        \u003cversion\u003e1.4.1\u003c/version\u003e\n        \u003ctype\u003epom\u003c/type\u003e\n    \u003c/dependency\u003e\n    \u003cdependency\u003e\n        \u003cgroupId\u003ecom.dinstone.focus\u003c/groupId\u003e\n        \u003cartifactId\u003efocus-client-photon\u003c/artifactId\u003e\n        \u003cversion\u003e1.4.1\u003c/version\u003e\n        \u003ctype\u003epom\u003c/type\u003e\n    \u003c/dependency\u003e\n    \u003cdependency\u003e\n        \u003cgroupId\u003ecom.dinstone.focus\u003c/groupId\u003e\n        \u003cartifactId\u003efocus-serialize-json\u003c/artifactId\u003e\n        \u003cversion\u003e1.4.1\u003c/version\u003e\n    \u003c/dependency\u003e\n\u003c/dependencies\u003e\n```\n\n2. create FooService interface.\n\n```java\npackage focus.quickstart;\n\npublic interface FooService {\n\n    public String hello(String name);\n\n    public CompletableFuture\u003cString\u003e async(String name);\n}\n```\n\n3. create FooService implement.\n\n```java\npackage focus.quickstart.server;\n\nimport focus.quickstart.FooService;\n\npublic class FooServiceImpl implements FooService {\n\n    public String hello(String name) {\n        return \"hello \" + name;\n    }\n\n    public CompletableFuture\u003cString\u003e async(String name) {\n        return CompletableFuture.completedFuture(\"async hello \" + name);\n    }\n}\n```\n\n4. create focus server and exporting service.\n\n```java\npackage focus.quickstart.server;\n\nimport java.io.IOException;\n\nimport com.dinstone.focus.server.FocusServer;\nimport com.dinstone.focus.server.ServerOptions;\nimport com.dinstone.loghub.Logger;\nimport com.dinstone.loghub.LoggerFactory;\n\nimport focus.quickstart.FooService;\n\npublic class FocusServerBootstrap {\n\n    private static final Logger LOG = LoggerFactory.getLogger(FocusServerBootstrap.class);\n\n    public static void main(String[] args) {\n\t\tServerOptions serverOptions = new ServerOptions(\"focus.quickstart.server\").listen(\"localhost\", 3333);\n\t\tFocusServer server = new FocusServer(serverOptions);\n\n\t\t// exporting service\n\t\tserver.exporting(FooService.class, new FooServiceImpl());\n\n\t\tserver.start();\n\t\tLOG.info(\"server start\");\n\t\ttry {\n\t\t\tSystem.in.read();\n\t\t} catch (IOException e) {\n\t\t\te.printStackTrace();\n\t\t}\n\t\tserver.close();\n\t\tLOG.info(\"server stop\");\n    }\n\n}\n```\n\n5. create focus client to importing service and invoke RPC.\n\n```java\npackage focus.quickstart.client;\n\nimport com.dinstone.focus.client.ClientOptions;\nimport com.dinstone.focus.client.FocusClient;\n\nimport focus.quickstart.FooService;\n\npublic class FocusClientBootstrap {\n\n\tpublic static void main(String[] args) throws Exception {\n\t\tClientOptions option = new ClientOptions(\"focus.quickstart.client\").connect(\"localhost\", 3333);\n\t\tFocusClient client = new FocusClient(option);\n\t\ttry {\n\t\t\tFooService fooService = client.importing(FooService.class);\n\t\t\tString reply = fooService.hello(\"dinstone\");\n\t\t\tSystem.out.println(reply);\n\n\t\t\tCompletableFuture\u003cString\u003e rf = fooService.async(\"dinstone\");\n\t\t\tSystem.out.println(rf.get());\n\t\t} finally {\n\t\t\tclient.close();\n\t\t}\n\t}\n}\n```\n\n### Asynchronous calls\n\n1. another way to call RPC asynchronously is to create an asynchronous interface class in client side.\n\n```java\npackage focus.quickstart.client;\n\nimport java.util.concurrent.CompletableFuture;\n\npublic interface FooAsyncService {\n    public CompletableFuture\u003cString\u003e hello(String name);\n}\n```\n\n2. create focus client to importing service and async invoke RPC.\n\n```java\npackage focus.quickstart.client;\n\nimport java.util.concurrent.CompletableFuture;\n\nimport com.dinstone.focus.client.ClientOptions;\nimport com.dinstone.focus.client.FocusClient;\nimport com.dinstone.focus.client.ImportOptions;\n\npublic class FocusClientAsyncCallBootstrap {\n\n\tpublic static void main(String[] args) throws Exception {\n\t\tClientOptions option = new ClientOptions(\"focus.quickstart.client\").connect(\"localhost\", 3333);\n\t\tFocusClient client = new FocusClient(option);\n\t\ttry {\n\t\t\tImportOptions importOptions = new ImportOptions(\"focus.quickstart.api.FooService\");\n\t\t\tFooAsyncService fooService = client.importing(FooAsyncService.class, importOptions);\n\t\t\tCompletableFuture\u003cString\u003e replyFuture = fooService.hello(\"dinstone\");\n\t\t\tSystem.out.println(replyFuture.get());\n\t\t} finally {\n\t\t\tclient.close();\n\t\t}\n\t}\n\n}\n```\n\n### Generic calls\n\n1. the generalized call does not need to build the client interface class\n\n2. create focus client to importing GenericService and sync/async invoke RPC.\n\n```java\npackage focus.quickstart.client;\n\nimport java.util.concurrent.CompletableFuture;\n\nimport com.dinstone.focus.client.ClientOptions;\nimport com.dinstone.focus.client.FocusClient;\nimport com.dinstone.focus.client.GenericService;\n\npublic class FocusClientGenericCallBootstrap {\n\n\tpublic static void main(String[] args) throws Exception {\n\t\tClientOptions option = new ClientOptions(\"focus.quickstart.client\").connect(\"localhost\", 3333);\n\t\tFocusClient client = new FocusClient(option);\n\t\ttry {\n\t\t\tGenericService genericService = client.generic(\"focus.quickstart.server\",\n\t\t\t\t\t\"focus.quickstart.api.FooService\");\n\n\t\t\tString reply = genericService.sync(String.class, \"hello\", \"dinstone\");\n\t\t\tSystem.out.println(\"sync call reply : \" + reply);\n\n\t\t\tCompletableFuture\u003cString\u003e replyFuture = genericService.async(String.class, \"hello\", \"dinstone\");\n\t\t\tSystem.out.println(\"async call reply : \" + replyFuture.get());\n\t\t} finally {\n\t\t\tclient.close();\n\t\t}\n\t}\n\n}\n```\n\n### Secure Call\n\n1.Set server parameters, enable SSL in the accept options, and set certificate information.\n\n```java\npackage focus.quickstart.ssl;\n\nimport java.io.IOException;\nimport java.security.cert.X509Certificate;\n\nimport com.dinstone.focus.server.FocusServer;\nimport com.dinstone.focus.server.ServerOptions;\nimport com.dinstone.focus.transport.photon.PhotonAcceptOptions;\n\nimport focus.quickstart.api.FooService;\nimport focus.quickstart.service.FooServiceImpl;\nimport io.netty.handler.ssl.util.SelfSignedCertificate;\n\npublic class SslFocusServerBootstrap {\n\n    public static void main(String[] args) throws Exception {\n\n        // setting ssl\n        SelfSignedCertificate cert = new SelfSignedCertificate();\n        PhotonAcceptOptions acceptOptions = new PhotonAcceptOptions();\n        acceptOptions.setEnableSsl(true);\n        acceptOptions.setPrivateKey(cert.key());\n        acceptOptions.setCertChain(new X509Certificate[] { cert.cert() });\n\n        // setting accept options\n        ServerOptions serverOptions = new ServerOptions(\"focus.quickstart.server\").listen(\"localhost\", 3333)\n                .setAcceptOptions(acceptOptions);\n\n        FocusServer server = new FocusServer(serverOptions);\n\n        // exporting service\n        server.exporting(FooService.class, new FooServiceImpl());\n\n        server.start();\n        try {\n            System.in.read();\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n        server.close();\n    }\n}\n```\n\n2.Set client parameters and enable SSL in the connection options.\n\n```java\npackage focus.quickstart.ssl;\n\nimport java.util.concurrent.CompletableFuture;\n\nimport com.dinstone.focus.client.ClientOptions;\nimport com.dinstone.focus.client.FocusClient;\nimport com.dinstone.focus.transport.photon.PhotonConnectOptions;\n\nimport focus.quickstart.api.FooService;\n\npublic class SslFocusClientBootstrap {\n\n    public static void main(String[] args) throws Exception {\n        PhotonConnectOptions connectOptions = new PhotonConnectOptions();\n        // setting ssl\n        connectOptions.setEnableSsl(true);\n        ClientOptions clientOptions = new ClientOptions(\"focus.quickstart.client\").connect(\"localhost\", 3333)\n                .setConnectOptions(connectOptions);\n        FocusClient client = new FocusClient(clientOptions);\n        try {\n            FooService fooService = client.importing(FooService.class);\n            String reply = fooService.hello(\"dinstone\");\n            System.out.println(reply);\n\n            CompletableFuture\u003cString\u003e rf = fooService.async(\"dinstone\");\n            System.out.println(rf.get());\n        } finally {\n            client.close();\n        }\n    }\n\n}\n```\n\n## Documents\n\n- [Wiki](https://github.com/dinstone/focus/wiki)\n- [Wiki(中文)](https://github.com/dinstone/focus/wiki/home_zh)\n\n# License\n\nFocus RPC is released under the [Apache License 2.0](http://www.apache.org/licenses/LICENSE-2.0).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdinstone%2Ffocus","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdinstone%2Ffocus","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdinstone%2Ffocus/lists"}