{"id":15043709,"url":"https://github.com/typ0520/bizsocket","last_synced_at":"2025-04-05T15:06:06.981Z","repository":{"id":206005876,"uuid":"72816730","full_name":"typ0520/bizsocket","owner":"typ0520","description":"异步socket，对一些业务场景做了支持","archived":false,"fork":false,"pushed_at":"2019-10-22T07:24:01.000Z","size":156,"stargazers_count":476,"open_issues_count":7,"forks_count":141,"subscribers_count":39,"default_branch":"master","last_synced_at":"2025-03-29T14:07:10.370Z","etag":null,"topics":["android","client","java","socket","socket-io","socket-io-client","socket-programming","socketio","sockets","tcp","tcp-client","tcp-server"],"latest_commit_sha":null,"homepage":null,"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/typ0520.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":"2016-11-04T05:21:13.000Z","updated_at":"2025-02-12T10:42:50.000Z","dependencies_parsed_at":"2023-11-07T15:03:42.898Z","dependency_job_id":null,"html_url":"https://github.com/typ0520/bizsocket","commit_stats":null,"previous_names":["typ0520/bizsocket"],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/typ0520%2Fbizsocket","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/typ0520%2Fbizsocket/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/typ0520%2Fbizsocket/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/typ0520%2Fbizsocket/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/typ0520","download_url":"https://codeload.github.com/typ0520/bizsocket/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247353731,"owners_count":20925329,"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":["android","client","java","socket","socket-io","socket-io-client","socket-programming","socketio","sockets","tcp","tcp-client","tcp-server"],"created_at":"2024-09-24T20:49:28.321Z","updated_at":"2025-04-05T15:06:06.956Z","avatar_url":"https://github.com/typ0520.png","language":"Java","readme":"# bizsocket\n\n[![license](https://img.shields.io/hexpm/l/plug.svg)](https://raw.githubusercontent.com/baidao/bizsocket/master/LICENSE)\n\n[ ![Download](https://api.bintray.com/packages/typ0520/maven/com.github.typ0520%3Abizsocket-core/images/download.svg) ](https://bintray.com/typ0520/maven/com.github.typ0520%3Abizsocket-core/_latestVersion)\n\n## 异步socket，对一些业务场景做了支持\n\n- 断线重连\n- 一对一请求\n- 通知、粘性通知\n- 串行请求合并\n- 包分片处理(AbstractFragmentRequestQueue)\n- 缓存\n- 拦截器\n- 支持rxjava，提供类似于retrofit的支持\n- 提供rxjava和rxjava2两种使用方式\n\n## 使用方式\n### RxJava2\n\nMaven\n\n```\n\u003cdependency\u003e\n  \u003cgroupId\u003ecom.github.typ0520\u003c/groupId\u003e\n  \u003cartifactId\u003ebizsocket-rx2\u003c/artifactId\u003e\n  \u003cversion\u003e2.0.0\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\nor Gradle\n\n```gradle\nbuildscript {\n\trepositories {\n\t   jcenter()\n\t}\n}\n \ndependencies {\n\tcompile 'com.github.typ0520:bizsocket-rx2:2.0.0'\n}\n```\n### RxJava\n\nMaven\n\n```\n\u003cdependency\u003e\n  \u003cgroupId\u003ecom.github.typ0520\u003c/groupId\u003e\n  \u003cartifactId\u003ebizsocket-rx1\u003c/artifactId\u003e\n  \u003cversion\u003e2.0.0\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\nor Gradle\n\n```gradle\nbuildscript {\n\trepositories {\n\t   jcenter()\n\t}\n}\n \ndependencies {\n\tcompile 'com.github.typ0520:bizsocket-rx1:2.0.0'\n}\n```\n\n## 适用协议\n\n如果想使用此库，客户端和服务器的通讯协议中必须要有命令号、包序列号这两个字段\n\n- 命令号代表请求类型，可以想象成http中url的作用\n- 包序列号是数据包的唯一索引，客户端发起请求时为数据包生成一个唯一索引，服务器返回请求对应的结果时把这个包序列号带回去\n\n协议可以类似于下面这种：\n\n| cmd        | packetId | contentLength |content|\n| -----------|:-------------:| ---------------------------:| ---------------------------:|\n|int         |int            |           int            |           byte[]            |\n\n也可以类似于下面这样的每个数据包都是一段json字符串，包与包之间用换行符分割\n\n```json\n{\"cmd\": xxx , \"packetId\": xxx , ...... } \n```\n\n数据包的创建是通过这两个抽象类PacketFactory、Packet，整个库的数据流转都是通过命令号、包序列号这两个字段来完成的，字段名、出现的位置以及形式不限，只要有这两个字段就适用此库\n\n## 配置BizSocket\n\nsample中client与server之间的通讯协议是\n\n| length(int)  | cmd(int) |   seq(int)        |   content(byte[])               |\n| -------------|:--------:| -----------------:| -------------------------------:|\n| 数据包的总长度 |  命令号   |  数据包的唯一索引     | 报文体，可以想象成http协议中的body |\n\n下面的代码片段来自[sample](https://github.com/typ0520/bizsocket/sample/j2se)，建议把代码拉下来看\n\n\n- 1、 首先需要创建一个数据包类继承自Packet\n\n```java\npublic class SamplePacket extends Packet {\n    static volatile int currentSeq = 0;\n    public int length;\n    public int cmd;\n    public int seq;\n    public String content;\n    \n    @Override\n    public int getCommand() {\n    \t //覆盖父类的抽象方法\n        return cmd;\n    }\n\n    @Override\n    public String getPacketID() {\n        //覆盖父类的抽象方法\n        return String.valueOf(seq);\n    }\n    \n    //获取请求数据包byte[]，写给服务器\n    public byte[] toBytes() {\n        ByteArrayOutputStream bos = new ByteArrayOutputStream();\n        BufferedSink bufferedSink = Okio.buffer(Okio.sink(bos));\n        try {\n            //包长 = 内容长度 + 包头固定的12个字节\n            ByteString byteString = ByteString.encodeUtf8(content);\n            bufferedSink.writeInt(byteString.size() + 12);\n            bufferedSink.writeInt(cmd);\n            bufferedSink.writeInt(seq);\n            bufferedSink.write(byteString);\n            bufferedSink.flush();\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n        return bos.toByteArray();\n    }\n}\n```\n\n- 2、创建PacketFactory，主要用来从流中解析出server发给client的数据包\n\n```java\npublic class SamplePacketFactory extends PacketFactory {\n    @Override\n    public Packet getRequestPacket(Packet reusable,Request request) {\n        return new SamplePacket(request.command(),request.body());\n    }\n\n    @Override\n    public Packet getHeartBeatPacket(Packet reusable) {\n        return new SamplePacket(SampleCmd.HEARTBEAT.getValue(), ByteString.encodeUtf8(\"{}\"));\n    }\n\n    @Override\n    public Packet getRemotePacket(Packet reusable,BufferedSource source) throws IOException {\n      \t SamplePacket packet = new SamplePacket();\n        packet.length = reader.readInt();\n        packet.cmd = reader.readInt();\n        packet.seq = reader.readInt();\n        //减去协议头的12个字节长度\n        packet.content = reader.readString(packet.length - 12, Charset.forName(\"utf-8\"));\n        return packet;\n    }\n}\n```\n\n- 3、配置client\n\n```java\npublic class SampleClient extends AbstractBizSocket {\n    public SampleClient(Configuration configuration) {\n        super(configuration);\n    }\n\n    @Override\n    protected PacketFactory createPacketFactory() {\n        return new SamplePacketFactory();\n    }\n}\n```\n\n- 3、启动client，以j2se为例写一个main方法\n\n```java\npublic static void main(String[] args) {\n        SampleClient client = new SampleClient(new Configuration.Builder()\n                .host(\"127.0.0.1\")\n                .port(9103)\n                .readTimeout(TimeUnit.SECONDS,30)\n                .heartbeat(60)\n                .build());\n\n        client.getInterceptorChain().addInterceptor(new Interceptor() {\n            @Override\n            public boolean postRequestHandle(RequestContext context) throws Exception {\n                System.out.println(\"发现一个请求postRequestHandle: \" + context);\n                return false;\n            }\n\n            @Override\n            public boolean postResponseHandle(int command, Packet responsePacket) throws Exception {\n                System.out.println(\"收到一个包postResponseHandle: \" + responsePacket);\n                return false;\n            }\n        });\n\n        try {\n            //连接\n            client.connect();\n            //启动断线重连\n            client.getSocketConnection().bindReconnectionManager();\n            //开启心跳\n            client.getSocketConnection().startHeartBeat();\n        } catch (Exception e) {\n            e.printStackTrace();\n        }\n\n        //注册通知，接收服务端的推送\n        client.subscribe(client, SampleCmd.NOTIFY_PRICE.getValue(), new ResponseHandler() {\n            @Override\n            public void sendSuccessMessage(int command, ByteString requestBody, Packet responsePacket) {\n                System.out.println(\"cmd: \" + command + \" ,requestBody: \" + requestBody + \" responsePacket: \" + responsePacket);\n            }\n\n            @Override\n            public void sendFailureMessage(int command, Throwable error) {\n                System.out.println(command + \" ,err: \" + error);\n            }\n        });\n\n\t//发起一对一请求\n        String json = \"{\\\"productId\\\" : \\\"1\\\",\\\"isJuan\\\" : \\\"0\\\",\\\"type\\\" : \\\"2\\\",\\\"sl\\\" : \\\"1\\\"}\";\n        client.request(new Request.Builder().command(SampleCmd.CREATE_ORDER.getValue()).utf8body(json).build(), new ResponseHandler() {\n            @Override\n            public void sendSuccessMessage(int command, ByteString requestBody, Packet responsePacket) {\n                System.out.println(\"cmd: \" + command + \" ,requestBody: \" + requestBody + \" attach: \" + \" responsePacket: \" + responsePacket);\n            }\n\n            @Override\n            public void sendFailureMessage(int command, Throwable error) {\n                System.out.println(command + \" ,err: \" + error);\n            }\n        });\n\n\t//如果想用rxjava的形式调用也是支持的,提供了类似于retrofit通过动态代理创建的service类来调用\n        BizSocketRxSupport rxSupport = new BizSocketRxSupport.Builder()\n                .requestConverter(new JSONRequestConverter())\n                .responseConverter(new JSONResponseConverter())\n                .bizSocket(client)\n                .build();\n        SampleService service = rxSupport.create(SampleService.class);\n\n        JSONObject params = new JSONObject();\n        try {\n            params.put(\"pageSize\",\"10000\");\n        } catch (JSONException e) {\n            e.printStackTrace();\n        }\n        //rxjava范例,使用rxjava2需修改Subscriber\n        service.queryOrderList(params).subscribe(new Subscriber\u003cJSONObject\u003e() {\n            @Override\n            public void onCompleted() {\n\n            }\n\n            @Override\n            public void onError(Throwable e) {\n\n            }\n\n            @Override\n            public void onNext(JSONObject jsonObject) {\n                System.out.println(\"rx response: \" + jsonObject);\n            }\n        });\n\n\t//阻塞主线程，防止程序退出，可以想象成android中的Looper类\n        while (true) {\n            try {\n                Thread.sleep(10000);\n            } catch (InterruptedException e) {\n                e.printStackTrace();\n            }\n        }\n    }\n```\n","funding_links":[],"categories":["网络编程"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftyp0520%2Fbizsocket","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftyp0520%2Fbizsocket","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftyp0520%2Fbizsocket/lists"}