RSocket Client CLI (RSC)
Aiming to be a curl for RSocket
usage: rsc [options] uri
Non-option arguments:
[String: uri]
Option Description
------ -----------
--ab, --authBearer [String] Enable Authentication Metadata
Extension (Bearer).
--authBasic [String] [DEPRECATED] Enable Authentication
Metadata Extension (Basic). This
Metadata exists only for the
backward compatibility with Spring
Security 5.2
--channel Shortcut of --im REQUEST_CHANNEL
--completion [ShellType] Output shell completion code for the
specified shell (bash, zsh, fish,
powershell)
-d, --data [String] Data. Use '-' to read data from
standard input. (default: )
--dataMimeType, --dmt [String] MimeType for data (default:
application/json)
--debug Enable FrameLogger
--delayElements [Long] Enable delayElements(delay) in milli
seconds
--dumpOpts Dump options as a file that can be
loaded by --optsFile option
--fnf Shortcut of --im FIRE_AND_FORGET
-h, --help [String] Print help
--im, --interactionModel InteractionModel (default:
[InteractionModel] REQUEST_RESPONSE)
-l, --load [String] Load a file as Data. (e.g. ./foo.txt,
/tmp/foo.txt, https://example.com)
--limitRate [Integer] Enable limitRate(rate)
--log [String] Enable log()
-m, --metadata [String] Metadata (default: )
--metadataMimeType, --mmt [String] MimeType for metadata (default:
application/json)
--optsFile [String] Configure options from a YAML file (e.
g. ./opts.yaml, /tmp/opts.yaml,
https://example.com/opts.yaml)
--printB3 Print B3 propagation info. Ignored
unless --trace is set.
-q, --quiet Disable the output on next
-r, --route [String] Enable Routing Metadata Extension
--request Shortcut of --im REQUEST_RESPONSE
--resume [Integer] Enable resume. Resume session duration
can be configured in seconds.
--retry [Integer] Enable retry. Retry every 1 second
with the given max attempts.
--sd, --setupData [String] Data for Setup payload
--setupMetadata, --sm [String] Metadata for Setup payload
--setupMetadataMimeType, --smmt Metadata MimeType for Setup payload
[String] (default: application/json)
--showSystemProperties Show SystemProperties for troubleshoot
--stacktrace Show Stacktrace when an exception
happens
--stream Shortcut of --im REQUEST_STREAM
--take [Integer] Enable take(n)
--trace [TracingMetadataCodec$Flags] Enable Tracing (Zipkin) Metadata
Extension. Unless sampling state
(UNDECIDED, NOT_SAMPLE, SAMPLE,
DEBUG) is specified, DEBUG is used
if no state is specified.
--trustCert [String] PEM file for a trusted certificate. (e.
g. ./foo.crt, /tmp/foo.crt, https:
//example.com/foo.crt)
-u, --as, --authSimple [String] Enable Authentication Metadata
Extension (Simple). The format must
be 'username:password'.
-v, --version Print version
-w, --wiretap Enable wiretap
--wsHeader, --wsh [String] Header for web socket connection
--zipkinUrl [String] Zipkin URL to send a span (e.g. http:
//localhost:9411). Ignored unless --
trace is set.
Install
Download an executable jar or native binary from Releases.
To get rsc
binary working on Windows, you will need to install Visual C++ Redistributable Packages in advance.
Install via Homebrew (Mac / Linux)
You can install native binary for Mac or Linux via Homebrew.
brew install making/tap/rsc
Install via Scoop (Windows)
You can install native binary for Windows via Scoop.
scoop bucket add making https://github.com/making/scoop-bucket.git
scoop update
scoop install rsc
Install via Coursier (Mac / Linux / Windows)
If you do not already have couriser installed on your machine, install it following steps given here: https://get-coursier.io/docs/cli-installation.
To install the graalvm binary do:
cs install rsc --contrib
To install the jvm binary (executable jar) do:
cs install rscj --contrib
Example usages
rsc --request --route=uppercase --data=Foo --debug tcp://localhost:7001
rsc --stream --route=hello --debug --take=30 ws://localhost:8080/rsocket
rsc --stream --route=searchTweets --data=Trump wss://demo.rsocket.io/rsocket
You can also send data via a file or URL using -l
/--load
option instead of -d
/--data
as follows
rsc --request --route=hello --load=./hello.txt --debug tcp://localhost:8080
rsc --request --route=hello --load=/tmp/hello.txt --debug tcp://localhost:8080
rsc --request --route=hello --load=https://example.com --debug tcp://localhost:8080
Enable shell autocompletion
rsc (0.8.0+) provides autocompletion support for Bash, Zsh, Fish and Powershell.
rsc --completion <SHELL>
shows the completion script.
If you install rsc
via Homebrew, the completion script is also installed under /usr/local/Homebrew/completions/
.
Below are the procedures to set up autocompletion manually.
Zsh
Add the following to the beginning of your ~/.zshrc
autoload -Uz compinit && compinit
You now need to ensure that the rsc completion script gets sourced in all your shell sessions.
echo 'source <(rsc --completion bash)' >>~/.zshrc
Bash
the completion script depends on bash-completion.
on Mac
the completion script doesn't work with Bash 3.2 which is the default bash version on Mac. It requires Bash 4.1+ and bash-completion v2.
You can install these as follows
brew install bash
brew install bash-completion@2
Make sure bash -v
shows 4.1+.
Add the bellow to your ~/.bash_profile
[[ -r "/usr/local/etc/profile.d/bash_completion.sh" ]] && . "/usr/local/etc/profile.d/bash_completion.sh"
You now need to ensure that the rsc completion script gets sourced in all your shell sessions.
echo 'source <(rsc --completion bash)' >>~/.bash_profile
on Linux
You can install bash-completion with apt-get install bash-completion
or yum install bash-completion
, etc.
Add source /usr/share/bash-completion/bash_completion
to your ~/.bashrc
.
You now need to ensure that the rsc completion script gets sourced in all your shell sessions.
echo 'source <(rsc --completion bash)' >>~/.bashrc
Fish
TBD (help wanted)
rsc --completion fish
Powershell
rsc --completion powershell | Out-String | Invoke-Expression
Log options
Default
By default, the data of the payload will be output (since 0.2.0).
$ rsc --route=add --data='{"x":10, "y":20}' tcp://localhost:7001
{"result":30}
Enable Reactor's log() operator
--log
option enables Reactive Stream Level log. --quiet
/-q
option disables the default output.
$ rsc --route=add --data='{"x":10, "y":20}' --log --quiet tcp://localhost:7001
2021-02-06 17:50:15.809 INFO 95810 --- [actor-tcp-nio-2] rsc : onSubscribe(FluxMap.MapSubscriber)
2021-02-06 17:50:15.809 INFO 95810 --- [actor-tcp-nio-2] rsc : request(unbounded)
2021-02-06 17:50:15.820 INFO 95810 --- [actor-tcp-nio-2] rsc : onNext({"result":30})
2021-02-06 17:50:15.820 INFO 95810 --- [actor-tcp-nio-2] rsc : onComplete()
Enable FrameLogger
--debug
option enables RSocket Level log.
$ rsc --route=add --data='{"x":10, "y":20}' --debug --quiet tcp://localhost:7001
2021-02-06 17:50:32.560 DEBUG 95820 --- [actor-tcp-nio-2] io.rsocket.FrameLogger : sending ->
Frame => Stream ID: 0 Type: SETUP Flags: 0b0 Length: 75
Data:
2021-02-06 17:50:32.560 DEBUG 95820 --- [actor-tcp-nio-2] io.rsocket.FrameLogger : sending ->
Frame => Stream ID: 1 Type: REQUEST_RESPONSE Flags: 0b100000000 Length: 33
Metadata:
+-------------------------------------------------+
| 0 1 2 3 4 5 6 7 8 9 a b c d e f |
+--------+-------------------------------------------------+----------------+
|00000000| fe 00 00 04 03 61 64 64 |.....add |
+--------+-------------------------------------------------+----------------+
Data:
+-------------------------------------------------+
| 0 1 2 3 4 5 6 7 8 9 a b c d e f |
+--------+-------------------------------------------------+----------------+
|00000000| 7b 22 78 22 3a 31 30 2c 20 22 79 22 3a 32 30 7d |{"x":10, "y":20}|
+--------+-------------------------------------------------+----------------+
2021-02-06 17:50:32.571 DEBUG 95820 --- [actor-tcp-nio-2] io.rsocket.FrameLogger : receiving ->
Frame => Stream ID: 1 Type: NEXT_COMPLETE Flags: 0b1100000 Length: 19
Data:
+-------------------------------------------------+
| 0 1 2 3 4 5 6 7 8 9 a b c d e f |
+--------+-------------------------------------------------+----------------+
|00000000| 7b 22 72 65 73 75 6c 74 22 3a 33 30 7d |{"result":30} |
+--------+-------------------------------------------------+----------------+
Enable Reactor's wiretap
--wiretap
/-w
option enables TCP Level log.
$ rsc --route=add --data='{"x":10, "y":20}' --wiretap --quiet tcp://localhost:7001
2021-02-06 17:51:20.140 DEBUG 95837 --- [actor-tcp-nio-2] reactor.netty.tcp.TcpClient : [id: 0x39d9fefe] REGISTERED
2021-02-06 17:51:20.141 DEBUG 95837 --- [actor-tcp-nio-2] reactor.netty.tcp.TcpClient : [id: 0x39d9fefe] CONNECT: localhost/127.0.0.1:7001
2021-02-06 17:51:20.141 DEBUG 95837 --- [actor-tcp-nio-2] reactor.netty.tcp.TcpClient : [id: 0x39d9fefe, L:/127.0.0.1:62801 - R:localhost/127.0.0.1:7001] ACTIVE
2021-02-06 17:51:20.141 DEBUG 95837 --- [actor-tcp-nio-2] reactor.netty.tcp.TcpClient : [id: 0x39d9fefe, L:/127.0.0.1:62801 - R:localhost/127.0.0.1:7001] WRITE: 78B
+-------------------------------------------------+
| 0 1 2 3 4 5 6 7 8 9 a b c d e f |
+--------+-------------------------------------------------+----------------+
|00000000| 00 00 4b 00 00 00 00 04 00 00 01 00 00 00 00 4e |..K............N|
|00000010| 20 00 01 5f 90 27 6d 65 73 73 61 67 65 2f 78 2e | .._.'message/x.|
|00000020| 72 73 6f 63 6b 65 74 2e 63 6f 6d 70 6f 73 69 74 |rsocket.composit|
|00000030| 65 2d 6d 65 74 61 64 61 74 61 2e 76 30 10 61 70 |e-metadata.v0.ap|
|00000040| 70 6c 69 63 61 74 69 6f 6e 2f 6a 73 6f 6e |plication/json |
+--------+-------------------------------------------------+----------------+
2021-02-06 17:51:20.142 DEBUG 95837 --- [actor-tcp-nio-2] reactor.netty.tcp.TcpClient : [id: 0x39d9fefe, L:/127.0.0.1:62801 - R:localhost/127.0.0.1:7001] WRITE: 36B
+-------------------------------------------------+
| 0 1 2 3 4 5 6 7 8 9 a b c d e f |
+--------+-------------------------------------------------+----------------+
|00000000| 00 00 21 00 00 00 01 11 00 00 00 08 fe 00 00 04 |..!.............|
|00000010| 03 61 64 64 7b 22 78 22 3a 31 30 2c 20 22 79 22 |.add{"x":10, "y"|
|00000020| 3a 32 30 7d |:20} |
+--------+-------------------------------------------------+----------------+
2021-02-06 17:51:20.142 DEBUG 95837 --- [actor-tcp-nio-2] reactor.netty.tcp.TcpClient : [id: 0x39d9fefe, L:/127.0.0.1:62801 - R:localhost/127.0.0.1:7001] FLUSH
2021-02-06 17:51:20.152 DEBUG 95837 --- [actor-tcp-nio-2] reactor.netty.tcp.TcpClient : [id: 0x39d9fefe, L:/127.0.0.1:62801 - R:localhost/127.0.0.1:7001] READ: 22B
+-------------------------------------------------+
| 0 1 2 3 4 5 6 7 8 9 a b c d e f |
+--------+-------------------------------------------------+----------------+
|00000000| 00 00 13 00 00 00 01 28 60 7b 22 72 65 73 75 6c |.......(`{"resul|
|00000010| 74 22 3a 33 30 7d |t":30} |
+--------+-------------------------------------------------+----------------+
2021-02-06 17:51:20.152 DEBUG 95837 --- [actor-tcp-nio-2] reactor.netty.tcp.TcpClient : [id: 0x39d9fefe, L:/127.0.0.1:62801 - R:localhost/127.0.0.1:7001] READ COMPLETE
Setup payload
The data in SETUP
payload can be specified by --setupData
/--sd
option and metadata can be specified by --setupMetaData
/--smd
.
Also the MIME type of the setup metadata can be specified by --setupMetadataMimeType
/--smmt
option.
For example:
rsc --setupData=foo --setupMetadata='{"value":"metadata"}' --setupMetadataMimeType=application/json --route=add --data='{"x":10, "y":20}' tcp://localhost:7001
As of 0.6.0, the following MIME types are supported.
application/json
(default)text/plain
message/x.rsocket.authentication.v0
message/x.rsocket.authentication.basic.v0
message/x.rsocket.application+json
(0.7.1+)
Accordingly, enum name of SetupMetadataMimeType
instead can be used with --smmt
option
APPLICATION_JSON
TEXT_PLAIN
MESSAGE_RSOCKET_AUTHENTICATION
AUTHENTICATION_BASIC
APP_INFO
(0.7.1+)
Composite Metadata
rsc
always uses Composite Metadata Extension.
If multiple metadataMimeTypes are specified, they are automatically composed (the order matters).
$ rsc --metadataMimeType=text/plain --metadata=hello --metadataMimeType=application/json --metadata='{"hello":"world"}' --data='{"x":10, "y":20}' --wiretap --quiet tcp://localhost:7001
2021-02-06 18:00:29.100 DEBUG 95998 --- [actor-tcp-nio-2] reactor.netty.tcp.TcpClient : [id: 0x9c1425b3] REGISTERED
2021-02-06 18:00:29.101 DEBUG 95998 --- [actor-tcp-nio-2] reactor.netty.tcp.TcpClient : [id: 0x9c1425b3] CONNECT: localhost/127.0.0.1:7001
2021-02-06 18:00:29.101 DEBUG 95998 --- [actor-tcp-nio-2] reactor.netty.tcp.TcpClient : [id: 0x9c1425b3, L:/127.0.0.1:62844 - R:localhost/127.0.0.1:7001] ACTIVE
2021-02-06 18:00:29.102 DEBUG 95998 --- [actor-tcp-nio-2] reactor.netty.tcp.TcpClient : [id: 0x9c1425b3, L:/127.0.0.1:62844 - R:localhost/127.0.0.1:7001] WRITE: 78B
+-------------------------------------------------+
| 0 1 2 3 4 5 6 7 8 9 a b c d e f |
+--------+-------------------------------------------------+----------------+
|00000000| 00 00 4b 00 00 00 00 04 00 00 01 00 00 00 00 4e |..K............N|
|00000010| 20 00 01 5f 90 27 6d 65 73 73 61 67 65 2f 78 2e | .._.'message/x.|
|00000020| 72 73 6f 63 6b 65 74 2e 63 6f 6d 70 6f 73 69 74 |rsocket.composit|
|00000030| 65 2d 6d 65 74 61 64 61 74 61 2e 76 30 10 61 70 |e-metadata.v0.ap|
|00000040| 70 6c 69 63 61 74 69 6f 6e 2f 6a 73 6f 6e |plication/json |
+--------+-------------------------------------------------+----------------+
2021-02-06 18:00:29.102 DEBUG 95998 --- [actor-tcp-nio-2] reactor.netty.tcp.TcpClient : [id: 0x9c1425b3, L:/127.0.0.1:62844 - R:localhost/127.0.0.1:7001] WRITE: 58B
+-------------------------------------------------+
| 0 1 2 3 4 5 6 7 8 9 a b c d e f |
+--------+-------------------------------------------------+----------------+
|00000000| 00 00 37 00 00 00 01 11 00 00 00 1e a1 00 00 05 |..7.............|
|00000010| 68 65 6c 6c 6f 85 00 00 11 7b 22 68 65 6c 6c 6f |hello....{"hello|
|00000020| 22 3a 22 77 6f 72 6c 64 22 7d 7b 22 78 22 3a 31 |":"world"}{"x":1|
|00000030| 30 2c 20 22 79 22 3a 32 30 7d |0, "y":20} |
+--------+-------------------------------------------------+----------------+
2021-02-06 18:00:29.102 DEBUG 95998 --- [actor-tcp-nio-2] reactor.netty.tcp.TcpClient : [id: 0x9c1425b3, L:/127.0.0.1:62844 - R:localhost/127.0.0.1:7001] FLUSH
...
--route
option is still respected.
$ rsc --metadataMimeType=text/plain --metadata=hello --metadataMimeType=application/json --metadata='{"hello":"world"}' --route=add --data='{"x":10, "y":20}' --wiretap --quiet tcp://localhost:7001
2021-02-06 18:01:28.434 DEBUG 96015 --- [actor-tcp-nio-2] reactor.netty.tcp.TcpClient : [id: 0xf49f4cd5] REGISTERED
2021-02-06 18:01:28.435 DEBUG 96015 --- [actor-tcp-nio-2] reactor.netty.tcp.TcpClient : [id: 0xf49f4cd5] CONNECT: localhost/127.0.0.1:7001
2021-02-06 18:01:28.435 DEBUG 96015 --- [actor-tcp-nio-2] reactor.netty.tcp.TcpClient : [id: 0xf49f4cd5, L:/127.0.0.1:62848 - R:localhost/127.0.0.1:7001] ACTIVE
2021-02-06 18:01:28.436 DEBUG 96015 --- [actor-tcp-nio-2] reactor.netty.tcp.TcpClient : [id: 0xf49f4cd5, L:/127.0.0.1:62848 - R:localhost/127.0.0.1:7001] WRITE: 78B
+-------------------------------------------------+
| 0 1 2 3 4 5 6 7 8 9 a b c d e f |
+--------+-------------------------------------------------+----------------+
|00000000| 00 00 4b 00 00 00 00 04 00 00 01 00 00 00 00 4e |..K............N|
|00000010| 20 00 01 5f 90 27 6d 65 73 73 61 67 65 2f 78 2e | .._.'message/x.|
|00000020| 72 73 6f 63 6b 65 74 2e 63 6f 6d 70 6f 73 69 74 |rsocket.composit|
|00000030| 65 2d 6d 65 74 61 64 61 74 61 2e 76 30 10 61 70 |e-metadata.v0.ap|
|00000040| 70 6c 69 63 61 74 69 6f 6e 2f 6a 73 6f 6e |plication/json |
+--------+-------------------------------------------------+----------------+
2021-02-06 18:01:28.436 DEBUG 96015 --- [actor-tcp-nio-2] reactor.netty.tcp.TcpClient : [id: 0xf49f4cd5, L:/127.0.0.1:62848 - R:localhost/127.0.0.1:7001] WRITE: 66B
+-------------------------------------------------+
| 0 1 2 3 4 5 6 7 8 9 a b c d e f |
+--------+-------------------------------------------------+----------------+
|00000000| 00 00 3f 00 00 00 01 11 00 00 00 26 fe 00 00 04 |..?........&....|
|00000010| 03 61 64 64 a1 00 00 05 68 65 6c 6c 6f 85 00 00 |.add....hello...|
|00000020| 11 7b 22 68 65 6c 6c 6f 22 3a 22 77 6f 72 6c 64 |.{"hello":"world|
|00000030| 22 7d 7b 22 78 22 3a 31 30 2c 20 22 79 22 3a 32 |"}{"x":10, "y":2|
|00000040| 30 7d |0} |
+--------+-------------------------------------------------+----------------+
2021-02-06 18:01:28.437 DEBUG 96015 --- [actor-tcp-nio-2] reactor.netty.tcp.TcpClient : [id: 0xf49f4cd5, L:/127.0.0.1:62848 - R:localhost/127.0.0.1:7001] FLUSH
...
If you use --route/-r
option, you need to specify to --metadataMimeType/--mmt
option for the additional metadata even if the type is application/json
which is the default mime type.
For example:
rsc -r functionRouter --mmt application/json -m '{"function":"uppercase"}' -d 'RSocket' tcp://localhost:8080
Backpressure
The onNext
output can be delayed with the --delayElements
(milli seconds) option. Accordingly, the number of request
will be automatically adjusted.
$ rsc --stream --delayElements=100 --log --route=uppercase.stream --data=rsocket tcp://localhost:7001
2021-02-06 18:14:18.230 INFO 96438 --- [actor-tcp-nio-2] rsc : onSubscribe(FluxMap.MapSubscriber)
2021-02-06 18:14:18.230 INFO 96438 --- [actor-tcp-nio-2] rsc : request(32)
2021-02-06 18:14:18.235 INFO 96438 --- [actor-tcp-nio-2] rsc : onNext(RSOCKET)
2021-02-06 18:14:18.235 INFO 96438 --- [actor-tcp-nio-2] rsc : onNext(RSOCKET)
2021-02-06 18:14:18.235 INFO 96438 --- [actor-tcp-nio-2] rsc : onNext(RSOCKET)
2021-02-06 18:14:18.235 INFO 96438 --- [actor-tcp-nio-2] rsc : onNext(RSOCKET)
2021-02-06 18:14:18.235 INFO 96438 --- [actor-tcp-nio-2] rsc : onNext(RSOCKET)
2021-02-06 18:14:18.235 INFO 96438 --- [actor-tcp-nio-2] rsc : onNext(RSOCKET)
2021-02-06 18:14:18.235 INFO 96438 --- [actor-tcp-nio-2] rsc : onNext(RSOCKET)
2021-02-06 18:14:18.235 INFO 96438 --- [actor-tcp-nio-2] rsc : onNext(RSOCKET)
2021-02-06 18:14:18.235 INFO 96438 --- [actor-tcp-nio-2] rsc : onNext(RSOCKET)
2021-02-06 18:14:18.235 INFO 96438 --- [actor-tcp-nio-2] rsc : onNext(RSOCKET)
2021-02-06 18:14:18.235 INFO 96438 --- [actor-tcp-nio-2] rsc : onNext(RSOCKET)
2021-02-06 18:14:18.235 INFO 96438 --- [actor-tcp-nio-2] rsc : onNext(RSOCKET)
2021-02-06 18:14:18.235 INFO 96438 --- [actor-tcp-nio-2] rsc : onNext(RSOCKET)
2021-02-06 18:14:18.235 INFO 96438 --- [actor-tcp-nio-2] rsc : onNext(RSOCKET)
2021-02-06 18:14:18.235 INFO 96438 --- [actor-tcp-nio-2] rsc : onNext(RSOCKET)
2021-02-06 18:14:18.235 INFO 96438 --- [actor-tcp-nio-2] rsc : onNext(RSOCKET)
2021-02-06 18:14:18.235 INFO 96438 --- [actor-tcp-nio-2] rsc : onNext(RSOCKET)
2021-02-06 18:14:18.235 INFO 96438 --- [actor-tcp-nio-2] rsc : onNext(RSOCKET)
2021-02-06 18:14:18.235 INFO 96438 --- [actor-tcp-nio-2] rsc : onNext(RSOCKET)
2021-02-06 18:14:18.235 INFO 96438 --- [actor-tcp-nio-2] rsc : onNext(RSOCKET)
2021-02-06 18:14:18.235 INFO 96438 --- [actor-tcp-nio-2] rsc : onNext(RSOCKET)
2021-02-06 18:14:18.235 INFO 96438 --- [actor-tcp-nio-2] rsc : onNext(RSOCKET)
2021-02-06 18:14:18.236 INFO 96438 --- [actor-tcp-nio-2] rsc : onNext(RSOCKET)
2021-02-06 18:14:18.236 INFO 96438 --- [actor-tcp-nio-2] rsc : onNext(RSOCKET)
2021-02-06 18:14:18.236 INFO 96438 --- [actor-tcp-nio-2] rsc : onNext(RSOCKET)
2021-02-06 18:14:18.236 INFO 96438 --- [actor-tcp-nio-2] rsc : onNext(RSOCKET)
2021-02-06 18:14:18.236 INFO 96438 --- [actor-tcp-nio-2] rsc : onNext(RSOCKET)
2021-02-06 18:14:18.236 INFO 96438 --- [actor-tcp-nio-2] rsc : onNext(RSOCKET)
2021-02-06 18:14:18.236 INFO 96438 --- [actor-tcp-nio-2] rsc : onNext(RSOCKET)
2021-02-06 18:14:18.236 INFO 96438 --- [actor-tcp-nio-2] rsc : onNext(RSOCKET)
2021-02-06 18:14:18.236 INFO 96438 --- [actor-tcp-nio-2] rsc : onNext(RSOCKET)
2021-02-06 18:14:18.236 INFO 96438 --- [actor-tcp-nio-2] rsc : onNext(RSOCKET)
RSOCKET
RSOCKET
RSOCKET
RSOCKET
RSOCKET
RSOCKET
RSOCKET
RSOCKET
RSOCKET
RSOCKET
RSOCKET
RSOCKET
RSOCKET
RSOCKET
RSOCKET
RSOCKET
RSOCKET
RSOCKET
RSOCKET
RSOCKET
RSOCKET
RSOCKET
RSOCKET
2021-02-06 18:14:20.595 INFO 96438 --- [ parallel-8] rsc : request(24)
2021-02-06 18:14:20.598 INFO 96438 --- [actor-tcp-nio-2] rsc : onNext(RSOCKET)
2021-02-06 18:14:20.598 INFO 96438 --- [actor-tcp-nio-2] rsc : onNext(RSOCKET)
...
You can also limit the number of request
with --limitRate
option.
$ rsc --stream --delayElements=100 --limitRate=8 --log --route=uppercase.stream --data=rsocket tcp://localhost:7001
2021-02-06 18:06:04.919 INFO 96118 --- [actor-tcp-nio-2] rsc : onSubscribe(FluxMap.MapSubscriber)
2021-02-06 18:06:04.919 INFO 96118 --- [actor-tcp-nio-2] rsc : request(8)
2021-02-06 18:06:04.922 INFO 96118 --- [actor-tcp-nio-2] rsc : onNext(RSOCKET)
2021-02-06 18:06:04.922 INFO 96118 --- [actor-tcp-nio-2] rsc : onNext(RSOCKET)
2021-02-06 18:06:04.922 INFO 96118 --- [actor-tcp-nio-2] rsc : onNext(RSOCKET)
2021-02-06 18:06:04.922 INFO 96118 --- [actor-tcp-nio-2] rsc : onNext(RSOCKET)
2021-02-06 18:06:04.922 INFO 96118 --- [actor-tcp-nio-2] rsc : onNext(RSOCKET)
2021-02-06 18:06:04.922 INFO 96118 --- [actor-tcp-nio-2] rsc : onNext(RSOCKET)
2021-02-06 18:06:04.922 INFO 96118 --- [actor-tcp-nio-2] rsc : onNext(RSOCKET)
2021-02-06 18:06:04.922 INFO 96118 --- [actor-tcp-nio-2] rsc : onNext(RSOCKET)
RSOCKET
RSOCKET
RSOCKET
RSOCKET
RSOCKET
2021-02-06 18:06:05.435 INFO 96118 --- [ parallel-6] rsc : request(6)
2021-02-06 18:06:05.439 INFO 96118 --- [actor-tcp-nio-2] rsc : onNext(RSOCKET)
2021-02-06 18:06:05.439 INFO 96118 --- [actor-tcp-nio-2] rsc : onNext(RSOCKET)
2021-02-06 18:06:05.439 INFO 96118 --- [actor-tcp-nio-2] rsc : onNext(RSOCKET)
2021-02-06 18:06:05.439 INFO 96118 --- [actor-tcp-nio-2] rsc : onNext(RSOCKET)
2021-02-06 18:06:05.439 INFO 96118 --- [actor-tcp-nio-2] rsc : onNext(RSOCKET)
2021-02-06 18:06:05.439 INFO 96118 --- [actor-tcp-nio-2] rsc : onNext(RSOCKET)
RSOCKET
RSOCKET
RSOCKET
RSOCKET
RSOCKET
RSOCKET
2021-02-06 18:06:06.048 INFO 96118 --- [ parallel-12] rsc : request(6)
2021-02-06 18:06:06.050 INFO 96118 --- [actor-tcp-nio-2] rsc : onNext(RSOCKET)
2021-02-06 18:06:06.050 INFO 96118 --- [actor-tcp-nio-2] rsc : onNext(RSOCKET)
2021-02-06 18:06:06.050 INFO 96118 --- [actor-tcp-nio-2] rsc : onNext(RSOCKET)
2021-02-06 18:06:06.050 INFO 96118 --- [actor-tcp-nio-2] rsc : onNext(RSOCKET)
2021-02-06 18:06:06.050 INFO 96118 --- [actor-tcp-nio-2] rsc : onNext(RSOCKET)
2021-02-06 18:06:06.050 INFO 96118 --- [actor-tcp-nio-2] rsc : onNext(RSOCKET)
RSOCKET
RSOCKET
RSOCKET
RSOCKET
RSOCKET
RSOCKET
...
Tip: Using --limitRate 1 --delayElements 1000 --debug
is a convenient way to trace a stream.
Authentication
rsc
supports Authentication Extension since 0.6.0.
The demo application is here.
Note that since RSocket Java 1.0.3, username field length is extended.
rsc 0.6.0 uses RSocket Java 1.0.2. To support extended username, rsc 0.7.0 which uses RSocket Java 1.1.0 or above is required.
Simple Authentication Type
To send credentials per stream, use --authSimple <username>:<password>
option as follows:
rsc tcp://localhost:8888 --authSimple user:password -r hello -d World
For shorter options, --as
or -u
(like curl
!) are also available.
rsc tcp://localhost:8888 -u user:password -r hello -d World
To send credentials in SETUP
payload, use --sm simple:<username>:<password> --smmt message/x.rsocket.authentication.v0
as follows.
rsc tcp://localhost:8888 --sm simple:user:password --smmt message/x.rsocket.authentication.v0 -r hello -d World
slightly shorter version
rsc tcp://localhost:8888 --sm simple:user:password --smmt MESSAGE_RSOCKET_AUTHENTICATION -r hello -d World
Bearer Token Authentication Type
To send token per stream, use --authBearer <token>
option as follows:
rsc tcp://localhost:8888 --authBearer MY_TOKEN -r hello -d World
For shorter option, --ab
is also available.
To send credentials in SETUP
payload, use --sm token:<token> --smmt message/x.rsocket.authentication.v0
as follows.
rsc tcp://localhost:8888 --sm token:MY_TOKEN --smmt message/x.rsocket.authentication.v0 -r hello -d World
slightly shorter version
rsc tcp://localhost:8888 --sm token:MY_TOKEN --smmt MESSAGE_RSOCKET_AUTHENTICATION -r hello -d World
Basic Authentication
Basic Authentication is not a part of Authentication Extension. It was implemented by Spring Security 5.2 before the spec was standardized.
rsc
supports Basic Authentication for the backward compatibility with Spring Security 5.2.
To send credentials per stream, use --authBasic <username>:<password>
option as follows:
rsc tcp://localhost:8888 --authBasic user:password -r hello -d World
To send credentials in SETUP
payload, use --sm <username>:<password> --smmt message/x.rsocket.authentication.basic.v0
as follows.
rsc tcp://localhost:8888 --sm user:password --smmt message/x.rsocket.authentication.basic.v0 -r hello -d World
slightly shorter version
rsc tcp://localhost:8888 --sm user:password --smmt AUTHENTICATION_BASIC -r hello -d World
Tracing
rsc
supports Tracing (Zipkin) Metadata Extension since 0.5.0
The demo application is here.
$ rsc ws://localhost:8080/rsocket -r rr --trace --printB3 --zipkinUrl http://localhost:9411
Hello World!
b3=5f035ed7dd21129b105564ef64c90731-105564ef64c90731-d
TODOs
- Support resuming (0.3.0)
- Support Composite Metadata (0.3.0)
- Setup data (0.4.0)
- Setup Metadata (0.6.0)
- RSocket Authentication (0.6.0)
- Request Channel (0.4.0)
- Input from a file (0.8.0)
- Input from STDIN (0.4.0)
- RSocket Routing Broker
- Client side responder
Build
./mvnw clean package -Pnative -DskipTests
A native binary will be created in target/classes/rsc-(osx|linux|windows)-x86_64
depending on your OS.
For linux binary, you can use Docker:
./mvnw spring-boot:build-image -DskipTests
docker run --rm rsc:<version> --version
How to run E2E testing
git clone https://github.com/making/rsc-e2e
cd rsc-e2e
export RSC_PATH=...
export RSC_OIDCISSUERURL=https://uaa.run.pivotal.io/oauth/token # you can change this
export RSC_OIDCUSERNAME=...
export RSC_OIDCPASSWORD=...
./mvnw test
License
Licensed under the Apache License, Version 2.0.