Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
625dfce
chore: tidy spring websocket client files
tcheeric Oct 3, 2025
2d6a242
docs: add spring subscription example client
tcheeric Oct 3, 2025
924599e
fix: avoid blocking subscription close
tcheeric Oct 3, 2025
4b0a175
chore: add .qodana to gitignore
Oct 3, 2025
932d643
refactor(api): enable non-blocking subscription handling
Oct 3, 2025
d2635dc
refactor(api): restore override for decode method
Oct 3, 2025
14ad06b
docs(bech32): improve method documentation for encode and decode
Oct 3, 2025
e34c7c8
refactor(api): make classTypeTagsMap final for immutability
Oct 3, 2025
5a521f2
docs(schnorr): enhance method documentation for sign and verify
Oct 3, 2025
ab99fe4
refactor(api): remove unused id field from ZapRequest
Oct 3, 2025
b811357
refactor(api): remove redundant assertion handling in product event v…
Oct 3, 2025
22d3f93
refactor(api): restore override annotation for decode method
Oct 3, 2025
0bd966c
refactor(api): restore override annotation for decode method
Oct 3, 2025
024ec93
refactor(api): restore override annotation for decode method
Oct 3, 2025
ba98567
refactor(api): suppress resource warning for HttpClient instantiation
Oct 3, 2025
33543a3
refactor(api): restore override annotations and clean up method docum…
Oct 3, 2025
d0818b5
refactor(api): make relayName and relayUri final fields
Oct 3, 2025
74858ea
refactor: deleted files
Oct 3, 2025
03a405f
refactor(api): simplify tag addition logic in CalendarContent
Oct 3, 2025
5968fcc
refactor: update pull request template to clarify purpose section
Oct 3, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
docs: add spring subscription example client
  • Loading branch information
tcheeric committed Oct 3, 2025
commit 2d6a2428a4d0a33d592bc6bbce1d1da29d13d7cc
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ See [`docs/CODEBASE_OVERVIEW.md`](docs/CODEBASE_OVERVIEW.md) for details about r
## Examples
Examples are located in the [`nostr-java-examples`](./nostr-java-examples) module.

- [`SpringSubscriptionExample`](nostr-java-examples/src/main/java/nostr/examples/SpringSubscriptionExample.java)
shows how to open a non-blocking `NostrSpringWebSocketClient` subscription and close it after a
fixed duration.

## Streaming subscriptions

The client and API layers expose a non-blocking streaming API for long-lived subscriptions. Use
Expand Down
4 changes: 3 additions & 1 deletion docs/reference/nostr-java-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,9 @@ public void close()
`subscribe` opens a dedicated WebSocket per relay, returns immediately, and streams raw relay
messages to the provided listener. The returned `AutoCloseable` sends a `CLOSE` command and releases
resources when invoked. Because callbacks execute on the WebSocket thread, delegate heavy
processing to another executor to avoid stalling inbound traffic.
processing to another executor to avoid stalling inbound traffic. The
[`SpringSubscriptionExample`](../../nostr-java-examples/src/main/java/nostr/examples/SpringSubscriptionExample.java)
demonstrates how to open a subscription and close it after a fixed duration.

### Configuration
- `RetryConfig` – enables Spring Retry support.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package nostr.examples;

import java.time.Duration;
import java.util.Map;
import nostr.api.NostrSpringWebSocketClient;
import nostr.base.Kind;
import nostr.event.filter.Filters;
import nostr.event.filter.KindFilter;

/**
* Example showing how to open a non-blocking subscription using {@link NostrSpringWebSocketClient}
* and close it after a fixed duration.
*/
public class SpringSubscriptionExample {

private static final Map<String, String> RELAYS = Map.of("local", "ws://localhost:5555");
private static final Duration LISTEN_DURATION = Duration.ofSeconds(30);

public static void main(String[] args) throws Exception {
NostrSpringWebSocketClient client = new NostrSpringWebSocketClient();
client.setRelays(RELAYS);

Filters filters = new Filters(new KindFilter<>(Kind.TEXT_NOTE));

AutoCloseable subscription =
client.subscribe(
filters,
"example-subscription",
message -> System.out.printf("Received from relay: %s%n", message),
error ->
System.err.printf(
"Subscription error for %s: %s%n", RELAYS.keySet(), error.getMessage()));

try {
System.out.printf(
"Listening for %d seconds. Publish events to %s to see them here.%n",
LISTEN_DURATION.toSeconds(), RELAYS.values());
Thread.sleep(LISTEN_DURATION.toMillis());
} finally {
try {
subscription.close();
} finally {
client.close();
}
}
}
}
Loading