{"id":21684515,"url":"https://github.com/scaledrone/scaledrone-java","last_synced_at":"2025-04-12T07:52:03.572Z","repository":{"id":83637897,"uuid":"116287263","full_name":"ScaleDrone/scaledrone-java","owner":"ScaleDrone","description":"Scaledrone Java \u0026 Android WebSocket client","archived":false,"fork":false,"pushed_at":"2019-03-26T17:09:20.000Z","size":100,"stargazers_count":18,"open_issues_count":3,"forks_count":12,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-12T07:51:59.700Z","etag":null,"topics":["android","java","real-time","scaledrone","websocket","websocket-client"],"latest_commit_sha":null,"homepage":"https://www.scaledrone.com/","language":"Java","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/ScaleDrone.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}},"created_at":"2018-01-04T17:16:23.000Z","updated_at":"2024-12-08T04:49:10.000Z","dependencies_parsed_at":null,"dependency_job_id":"eb910ecb-2342-4000-9b84-0135eee5a46f","html_url":"https://github.com/ScaleDrone/scaledrone-java","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ScaleDrone%2Fscaledrone-java","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ScaleDrone%2Fscaledrone-java/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ScaleDrone%2Fscaledrone-java/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ScaleDrone%2Fscaledrone-java/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ScaleDrone","download_url":"https://codeload.github.com/ScaleDrone/scaledrone-java/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248537033,"owners_count":21120690,"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","java","real-time","scaledrone","websocket","websocket-client"],"created_at":"2024-11-25T16:15:56.953Z","updated_at":"2025-04-12T07:52:03.566Z","avatar_url":"https://github.com/ScaleDrone.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![travis master branch build status](https://travis-ci.org/ScaleDrone/scaledrone-java.svg?branch=master)](https://travis-ci.org/ScaleDrone/scaledrone-java)\n\n# Scaledrone Java/Android WebSocket client\n\n\u003e Use the Scaledrone Java client to connect to the Scaledrone realtime messaging service\n\nThis project goes hand to hand with [Scaledrone documentation](https://www.scaledrone.com/docs). It's still a work in progress, pull requests and issues are very welcome.\n\n## Installation\n\n[ ![Download](https://api.bintray.com/packages/scaledrone/scaledrone/scaledrone-java/images/download.svg) ](https://bintray.com/scaledrone/scaledrone/scaledrone-java/_latestVersion)\n\nThe library is hosted on the [Jcenter repository](https://bintray.com/scaledrone/scaledrone/scaledrone-java), so you need to ensure that the repo is referenced also; IDEs will typically include this by default:\n\n```\nrepositories {\n\tjcenter()\n}\n```\n\n### Maven\n\n```xml\n\u003cdependency\u003e\n  \u003cgroupId\u003ecom.scaledrone\u003c/groupId\u003e\n  \u003cartifactId\u003escaledrone-java\u003c/artifactId\u003e\n  \u003cversion\u003e0.7.0\u003c/version\u003e\n  \u003ctype\u003epom\u003c/type\u003e\n\u003c/dependency\u003e\n```\n\n### Gradle\n\n```\ncompile 'com.scaledrone:scaledrone-java:0.7.0'\n```\n\n## Android\n\nIf you are using this library on Android make sure you add the [INTERNET](https://developer.android.com/training/basics/network-ops/connecting.html) permission to the manifest file.\n```xml\n\u003cuses-permission android:name=\"android.permission.INTERNET\" /\u003e\n```\n\n## Getting started\n\n### Basic example\n\n```java\nfinal Scaledrone drone = new Scaledrone(\"CHANNEL_ID_FROM_DASHBOARD\");\ndrone.connect(new Listener() {\n    @Override\n    public void onOpen() {\n        drone.subscribe(\"myroom\", new RoomListener() {\n            @Override\n            public void onOpen(Room room) {\n                room.publish(\"Hello world\");\n            }\n\n            @Override\n            public void onOpenFailure(Room room, Exception ex) {\n                // This can happen when you don't have correct permissions\n                System.out.println(\"Failed to subscribe to room: \" + ex.getMessage());\n            }\n\n            @Override\n            public void onMessage(Room room, Message message) {\n                System.out.println(\"Message: \" + message.getData().asText());\n            }\n        });\n    }\n\n    @Override\n    public void onOpenFailure(Exception ex) {\n        System.out.println(\"Failed to open connection: \" + ex.getMessage());\n    }\n\n    @Override\n    public void onFailure(Exception ex) {\n        System.out.println(\"Unexcpected failure: \" + ex.getMessage());\n    }\n\n    @Override\n    public void onClosed(String reason) {\n        System.out.println(\"Connection closed: \" + reason);\n    }\n});\n```\n\n### Connection\n\nConnecting to a new channel is done by creating a new instance of `Scaledrone` and calling the `connect()` method. To create your own `channel_id` create a Scaledrone account and a new channel from [Scaledrone dashboard](https://dashboard.scaledrone.com/channels).\n\n```java\nfinal Scaledrone drone = new Scaledrone(\"channel_id\");\ndrone.connect(new Listener() {\n    // overwrite the Listener methods\n});\n```\n\n### Subscribing to messages\n\nSubscribing to messages is done by subscribing to a room. Rooms are used to group users into groups, to which we can then publish messages. You can subscribe to multiple rooms.\n\nA received message is of type `JsonNode`. Jackson `JsonNode` can easily be transferred into POJO or String.\n\n```java\ndrone.subscribe(\"myroom\", new RoomListener() {\n    @Override\n    public void onMessage(Room room, Message message) {\n        // parse as string\n        System.out.println(\"Message: \" + message.getData().asText());\n\n        // or parse as POJO\n        try {\n            ObjectMapper mapper = new ObjectMapper();\n            Pojo pojo = mapper.treeToValue(message.getData(), Pojo.class);\n            System.out.println(\"Message: \" + pojo);\n        } catch (JsonProcessingException e) {\n            e.printStackTrace();\n        }\n    }\n    // overwrite other methods\n});\n```\n\n### Publishing messages\n\nA published message will be converted to JSON using Jackson. You don't have to be subscribed to a room when publishing to it.\n\n```java\ndrone.publish(\"roomName\", data);\n// or\nroom.publish(data);\n```\n\n## Authentication\n\nUsing authentication is optional, it can be enabled from the channel settings page. Scaledrone uses JSON Web Token for authentication.\n\nA typical authentication flow happens after connecting to a channel. At that point the user would send the `drone.getClientID()` to your personal authentication server which returns a JSON Web Token. The token is then passed on to Scaledrone.\n\nUse the [jwt.io debugger](https://jwt.io) to help you debug your JWT tokens.\n\n```java\nfinal Scaledrone drone = new Scaledrone(\"channel_id\");\ndrone.connect(new Listener() {\n    @Override\n    public void onOpen() {\n        final String jwt = requestJWTFromYourAuthServer(drone.getClientID());\n        drone.authenticate(jwt, new AuthenticationListener() {\n            @Override\n            public void onAuthentication() {\n                // user is now connected to the channel\n            }\n\n            @Override\n            public void onAuthenticationFailure(Exception ex) {\n                // something went wront, probably a problem with the JWT\n            }\n        });\n    }\n    // overwrite methods\n```\n\nSee the Scaledrone [JWT authentication docs](https://www.scaledrone.com/docs/jwt-authentication) on what the token should look like.\nSee the [authentication tests](https://github.com/ScaleDrone/scaledrone-java/blob/master/src/test/java/com/scaledrone/AuthTest.java#L159-L178) to see how to generate a JWT on the server side.\n\n## Observable rooms\n\nObservable rooms act like regular rooms but provide additional events for keeping track of connected members.\nObservable room names need to be prefixed with `observable-`.\n\n```java\nfinal Scaledrone drone = new Scaledrone(\"channel_id\", data);\ndrone.connect(new Listener() {\n    @Override\n    public void onOpen() {\n        Room room = drone.subscribe(\"observable-myroom\", new RoomListener() {\n            // Overwrite regular room listener methods\n        });\n        room.listenToObservableEvents(listener, new ObservableRoomListener() {\n            @Override\n            public void onMembers(Room room, ArrayList\u003cMember\u003e members) {\n                // Emits an array of members that have joined the room. This event is only triggered once, right after the user has successfully connected to the observable room.\n                // Keep in mind that the session user will also be part of this array, so the minimum size of the array is 1\n\n                Member member = members.get(0);\n                ObjectMapper mapper = new ObjectMapper();\n                try {\n                    Data d = mapper.treeToValue(member.getClientData(), Data.class);\n                } catch (JsonProcessingException e) {\n\n                }\n            }\n\n            @Override\n            public void onMemberJoin(Room room, Member member) {\n                // A new member joined the room.\n            }\n\n            @Override\n            public void onMemberLeave(Room room, Member member) {\n                // A member left the room (or disconnected)\n            });\n        });\n    }\n```\n\n## Message history\n\nWhen creating a Scaledrone room you can supply the number of messages to recieve from that room's history. The messages will arrive, in reverse chronological order and one by one, in `scaledroneRoomDidReceiveMessage`, just like real-time messages.\n\nPass the `SubscribeOptions` as the second parameter to the `subscribe` method to define how many messages you would like to receive.\n\nYou can then listen to the history messages using `room.listenToHistoryEvents()`.\n\nIn order to recieve message history messages, this feature needs to be enabled in the [Scaledrone dashboard](http://dashboard.scaledrone.com). You can learn more about Message History and its limitations in [Scaledrone docs](https://www.scaledrone.com/docs/message-history).\n\n```java\n\nRoom room = drone.subscribe(roomName, new RoomListener() {\n    // implement the default RoomListener methods here\n}, new SubscribeOptions(50)); // ask for 50 messages from the history\n\nroom.listenToHistoryEvents(new HistoryRoomListener() {\n    @Override\n    public void onHistoryMessage(Room room, Message message) {\n        System.out.println('Received a message from the past ' + message.getData().asText());\n    }\n});\n```\n\n## Checking if the messages was sent by the user itself\n\n```java\n// inside a room listener\n@Override\npublic void onMessage(Room room, Message message) {\n    if (message.getClientID() == scaledrone.getClientID()) {\n        // message is sent by session user\n    }\n}\n```\n\n## Reconnecting\nThe currect version of the Java library doesn't reconnect automatically after a possible disconnect. This feature will be added in the future.\nTo handle reconnection you can listen to the `onFailure` event.\n```java\n@Override\npublic void onFailure(Exception ex) {\n    tryReconnecting(0);\n}\n\nprivate void tryReconnecting(final int reconnectAttempt) {\n    Timer timer = new Timer();\n    timer.schedule(new TimerTask() {\n        @Override\n        public void run() {\n            final Scaledrone drone = new Scaledrone(\"channel-id\");\n            drone.connect(new Listener() {\n                @Override\n                public void onFailure(Exception ex) {\n                    tryReconnecting(reconnectAttempt + 1);\n                }\n            });\n            // set everything up again..\n        }\n    }, reconnectAttempt * 1000);\n}\n```\n\n## Troubleshooting\n```\nPKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target\n```\nThis likely means that your Java doesn't support Let's Encrypt Certificates. Upgrade Java7 to 7u111 or newer or Java 8 to 8u101 or newer. [Read more..](https://stackoverflow.com/questions/34110426/does-java-support-lets-encrypt-certificates/35454903)\n\n## Publishing a new version to JCenter\n\n* Update the version 1.2.3 in `build.gradle`\n* Run `./gradlew java:assembleRelease` to generate the new release files\n* Go to https://bintray.com/scaledrone/scaledrone/scaledrone-java and create a new version\n* Click \"Upload Files\"\n* Type in `com/scaledrone/scaledrone-java/1.2.3` into \"Target Repository Path\" ensuring the correct version is included.\n* Upload all the files from `java/build/release/1.2.3/com/scaledrone/scaledrone-java/1.2.3`\n* You will see a notice \"You have 8 unpublished item(s) for this version\", click \"Publish\". It might take a few minutes\n* Update the README with the correct version\n\n## Changelog\n\n* `0.7.0` - Fixed parsing 'id' field from JSON message.\n* `0.6.0` - Added message history features. Created a `Message` class that wraps the sent data, member as well as new properties such as message ID, timestamp and clientID.\n* `0.5.0` - Add up `close()` method.\n* `0.4.0` - Hook up `onFailure` listener. This can be used for reconnecting.\n* `0.3.0` - Add `member` parameter to `onMessage` listener method.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fscaledrone%2Fscaledrone-java","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fscaledrone%2Fscaledrone-java","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fscaledrone%2Fscaledrone-java/lists"}