I am completely new to RSocket.
I read the FAQ and the motiviations page (and skimmed the Protocol page) and understand that RSocket can be used on top of TCP, WebSocket and Aeron. But what I don't understand is what the differences are between using RSocket with these transports because all interaction-models can be used with each transport.
I am personally interested in using RSocket channel to enable bi-directional communication but don't know which transport I should use.
For example what are the differences between RSocket (channel) + TCP and RSocket (channel) + WebSocket?
I couldn't find an answer anywhere, so I was hoping someone here could help me out.
Ty in advance.
RSocket let's you program across platforms (JS, iOS, Android, C++ Server) with a single reactive network programming model. Cleanly supporting common reactive operations from frameworks like RxJava (Observable, Flowable, Single, Maybe, Completable).
The underlying transport is an implementation detail. But it's a critical implementation detail as between a mobile and a server hosted in GCP, WebSocket may be the only viable option. While in a datacenter you may opt for Aeron or TCP depending on your requirements.
Whatever you choose, you can write against the same higher level model of reactive network operations. If you know you just need say Aeron for a single server to server operation, you may not need RSocket, you could program directly against Aeron. RSocket is giving you this abstraction above it.
RSocket provides a common programming interface to multiple transports. You can choose the transport based on the qualities of service the transport provides. For example, if you require ease of firewall traversal then choose WebSocket, if you require low-latency and high-throughput transfer choose Aeron. All things are relative. Aeron can traverse firewalls but configuration is more specialised and WebSocket can give reasonable performance but it is not in the same category as Aeron.
Many other factors come into play so you need to understand the underlying transports with the qualities they provide and match these up against your requirements.
Related
I was reading the the official RFC for the Web Sockets protocol in order to implement it for learning purposes, I wanted to make things a bit different somehow but I was not sure what to make different. While I was reading the document, I came across this:
The Web Socket Protocol attempts to address the goals of existing bidirectional HTTP technologies in the context of the existing HTTP infrastructure; as such, it is designed to work over HTTP ports 80 and 443 as well as to support HTTP proxies and intermediaries, even if this implies some complexity specific to then current environment. However, the design does not limit Web Socket to HTTP, and future implementations could use a simpler handshake over a dedicated port without reinventing the entire protocol.
Does this imply a custom web socket protocol can be implemented with a non http based handshake?.
If so, does it mean a the regular Java Script Web Socket client will not work with this and I would need to implement a custom client to communicate using this protocol?
I have recently come across a term 'Reactive sockets'. Up until this point, I used to think websockets are the way to go for full fledged asynchronous style.
So what are reactive sockets.
This link (http://rsocket.io/) even talks about comparison over websockets.
What is RSocket?
RSocket implements the Reactive Streams specification over the network boundary. It is an application-level communication protocol with framing, session resumption, and backpressure built-in that works over the network.
RSocket is transport agnostic. RSocket can be run over Websockets, TCP, HTTP/2, and Aeron.
How does RSocket differ from Websockets?
Websockets do not provide application-level backpressure, only TCP-based byte-level backpressure. Websockets also only provide framing they do not provide application semantics. It is up to the developer to build out an application protocol for interacting with the websocket.
RSocket provides framing, application semantics, application-level backpressure, and it is not tied to a specific transport.
For more information on the motivations behind the creation of RSocket checkout the motivations doc on the RSocket site.
Both WebSocket and RSocket are protocols which feature bi-directional, multiplex, duplex communication. But both work at different levels.
WebSocket is a low level communication protocol layered over TCP. It defines how a stream of bytes is transformed into frames. But WebSocket message itself does not have instructions about how to route or process it. Therefore, we need messaging protocols that operate on top of websocket, at application level, to achieve two-way communication.
RSocket is a fully reactive application level protocol which runs over byte stream transports such as TCP, WebSocket, UDP or other. It provides application flow control over the network to prevent outages and increase resiliency. RSocket employs the idea of asynchronous stream processing with non-blocking back-pressure, in which a failing component will, rather than simply dropping traffic, communicate its stress to upstream components, getting them to reduce the load.
Websocket
TLDR: L4 protocol, TCP for web.
Websocket is single bytestream, frames based protocol with very compact header.
It relies on web/http in each important protocol aspect: http based handshake (full roundtrip, not ideal for latency), text frames in addition to binary ones, compression support (for low-throughput/high latency connections),
mandatory frame content masking for compatibility with legacy non-tls http proxies.
Frames may be fragmented for better memory utilization by client and server;
Flow control is byte level only from TCP, and is not propagated to userspace.
Because websocket is just single bytestream transport, It needs full application protocol on top to be useful, and application level flow control scheme to be scalable.
Adoption wise, stable websocket implementation is available for most OSes / architectures, protocol is supported by all browsers and is go-to solution if any traffic needs to survive internet hop.
RSocket. Theory
TLDR: L5 protocol, primarily cloud/datacenter communications with excellent
throughput/latency characteristic: huge throughput while maintaining latency < few millis.
RSocket is session layer protocol, offers multiplexed flow controlled streams of binary messages over any transport capable of transferring bytes in order (tcp, unix sockets, also websocket).
Low latency is cornerstone, protocol has several capabilities for this:
2 levels of flow control: Reactive-Streams on individual stream level,
request leasing on connection level. Leasing is feature to control number of active streams by responder side using service & connection latency stats.
Instant handshake: client may send requests immediately after initial setup message.
Message fragmentation helps with reducing server memory pressure and improves latency for large messages (if done properly, see RSocket. Practice below).
Session resumption: reduced latency on client reconnection.
Because binary streaming interactions / multiplexing are available out-of-the-box, It is trivial to implement application RPC on top - only data serialization/deserialization is needed (mstreams-rpc using protobuf data encoding).
The protocol is semantically compatible with http2, which means It is also compatible with GRPC (given protobuf is used for message encoding).
RSocket. Practice
Only useful on JVM because that's where reactive streams are popular and practically useful with several
stable implementations: rxjava, project-reactor, smallrye-mutiny.
RSocket/RSocket-java is based on project-reactor from springboot.
Natural expectation would be best-in-class throughput, unfortunately RSocket/RSocket-java did not get this
right so performs worse
than 10+ year older GRPC (its predecessor Stubby was in use from ~2001) on top of http2: chatty web protocol.
Fragmentation: no server memory use or latency improvement because RSocket/RSocket-java
implemented It in pointless way - frames are always reassembled before passing
downstream.
GRPC compatibility: absent.
Advice for 2022: better stick with GRPC.
What are the major differences between WebSocket and STOMP protocols?
This question is similar to asking the difference between TCP and HTTP. I shall still try to address your question, its natural to get confused between these two terms if you are beginning.
Short Answer
STOMP is derived on top of WebSockets. STOMP just mentions a few specific ways on how the message frames are exchanged between the client and the server using WebSockets.
Long Answer
WebSockets
It is a specification to allow asynchronous bidirectional communication between a client and a server. While similar to TCP sockets, it is a protocol that operates as an upgraded HTTP connection, exchanging variable-length frames between the two parties, instead of a stream.
STOMP
It defines a protocol for clients and servers to communicate with messaging semantics. It does not define any implementation details, but rather addresses an easy-to-implement wire protocol for messaging integrations. It provides higher semantics on top of the WebSockets protocol and defines a handful of frame types that are mapped onto WebSockets frames. Some of these types are...
connect
subscribe
unsubscribe
send (messages sent to the server)
message (for messages send from the server) BEGIN, COMMIT, ROLLBACK
(transaction management)
WebSocket does imply a messaging architecture but does not mandate the use of any specific messaging protocol. It is a very thin layer over TCP that transforms a stream of bytes into a stream of messages (either text or binary) and not much more. It is up to applications to interpret the meaning of a message.
Unlike HTTP, which is an application-level protocol, in the WebSocket protocol there is simply not enough information in an incoming message for a framework or container to know how to route it or process it. Therefore WebSocket is arguably too low level for anything but a very trivial application. It can be done, but it will likely lead to creating a framework on top. This is comparable to how most web applications today are written using a web framework rather than the Servlet API alone.
For this reason the WebSocket RFC defines the use of sub-protocols. During the handshake, the client and server can use the header Sec-WebSocket-Protocol to agree on a sub-protocol, i.e. a higher, application-level protocol to use. The use of a sub-protocol is not required, but even if not used, applications will still need to choose a message format that both the client and server can understand. That format can be custom, framework-specific, or a standard messaging protocol.
STOMP — a simple, messaging protocol originally created for use in scripting languages with frames inspired by HTTP. STOMP is widely supported and well suited for use over WebSocket and over the web.
The WebSocket API enables web applications to handle bidirectional communications whereas STOMP is a simple text-orientated messaging protocol. A Bidirectional WebSocket allows a web server to initiate a new message to a client, rather than wait for the client to request updates. The message could be in any protocol that the client and server agree to.
The STOMP protocol is commonly used inside a web socket.
A good tutorial is STOMP Over WebSocket by Jeff Mesnill (2012)
STOMP can also be used without a websocket, e.g. over a Telnet connection or a message broking service.
And Raw WebSockets can be used without STOMP - Eg. Spring Boot + WebSocket example without STOMP and SockJs.
Note: Others have well explained what are both WebSocket and STOMP, so I'll try to add the missing bits.
The WebSocket protocol defines two types of messages (text and binary), but their content is undefined.
STOMP protocol defines a mechanism for client and server to negotiate a sub-protocol (that is, a higher-level messaging protocol) to use on top of WebSocket to define following things:
what kind of messages each can send,
what the format is,
the content of each message, and so on.
The use of a sub-protocol is optional but, either way, the client and the server need to agree on some protocol that defines message content.
Reference
TLDR; STOMP is a framework built on top of websockets, i.e. stomp utilizes websockets in the background. If you are thinking of building a notification/messaging system then use stomp.
https://stomp.github.io/stomp-specification-1.2.html
I'd like to compare somehow capabilities of grpc vs. zeromq & its patterns: and I'd like to create some comparsion (feature set) - somehow - 0mq is "better" sockets - but anyways - if I apply 0mq patterns - I get comparable 'frameworks' I think - and here 0mq seems to be much more flexible ...
The main requirements are:
async req / res communication (inproc or remote) between nodes
flexible messages routing
loadbalancing support
well documented
any ideas?
thanks!
async req / res communication (inproc or remote) between nodes
Both libraries allow for synchronous or asynchronous communication depending on how to implement the communication. See this page for gRPC: http://www.grpc.io/docs/guides/concepts.html. Basically gRPC allow for typical HTTP synchronous request/response or a 'websocket-like' bidirectional streaming. For 0mq you can setup a simple REQ-REP connection which is basically a synchronous communication path, or you can create async ROUTER-DEALER type topologies.
flexible messages routing
'Routing' essentially means that a message gets from A to B via some broker. This is trivially done in 0mq and there are a number of topologies that support stuff like this (http://zguide.zeromq.org/page:all#Basic-Reliable-Queuing-Simple-Pirate-Pattern). In gRPC the same sort of topology could be created with a 'pub-sub' like connection over a stream. gRPC supports putting metadata in the message (https://github.com/grpc/grpc-go/blob/master/Documentation/grpc-metadata.md) which will allow you to 'route' a message into a queue that a 'pub-sub' connection could pull from.
loadbalancing support
gRPC has a health check support (https://github.com/grpc/grpc/blob/master/doc/health-checking.md) but because it's HTTP/2 you'd have to have a HTTP/2 load balancer to support the health check. This isn't a huge big deal, however, because you can tie the health check to a HTTP/1.1 service which the load balancer calls. 0mq is a tcp connection which means that a load balancer would likely check a 'socket connect' in tcpmode to verify the connection. This works but it's not as nice. Again you could get slick and front-end the 0mq service with a HTTP/1.1 webserver that the load balancer reads from.
well documented
both are well documented. 0mq's documentation must be read to throughly understand the technology and is more of a higher lift.
Here's the big differences:
0mq is a tcp protocol whereas gRPC is HTTP with a binary payload.
0mq requries you design a framing protocol (frame 1 = verison, frame 2 = payload, etc.), whereas much of this work is done for you in gRPC
gRPC is transparently coverted to REST (https://github.com/grpc-ecosystem/grpc-gateway) whereas 0mq requires a middleware application if you want to talk REST to it.
gRPC uses standard tls x509 certificates (think websites) whereas 0mq uses a custom encryption/authentication protocol (http://curvezmq.org/). Prior to 4.x there was no encryption support in 0mq and if you really wanted it you had to dive into this crap: https://wiki.openssl.org/index.php/BIO. (trust me don't do it)
0mq can create some pretty sick topologies (https://github.com/zeromq/majordomo) (https://rfc.zeromq.org/spec:7/MDP/) whereas gRPC is basically client/server
0mq requires much more time to build and get running whereas gRPC is basically compiling a protobuf messages and importing the service into your code.
Not quite the same. gRPC is primarily for heterogeneous service interoperability, ZeroMQ (ZMQ/0MQ/ØMQ) is a lower level messaging framework. ØMQ doesn't specify payload serialization beyond passing binary blobs whereas gRPC chooses Protocol Buffers by default. ØMQ is pretty much stuck on the same machine or machines between datacenters/clouds, whereas gRPC could potentially work on a real client too (ie mobile or web, it already supports iOS). gRPC using ØMQ could be significantly faster and more efficient for in-cloud/-datacenter services than the overhead, latency and complexity of http2 request/response chain. I'm not sure how (or even if) gRPC TLS security is adequate for public cloud and mobile/web usage, but one could always inject end-to-end security requirements (ie libsodium) at the router/controller level of the app/app framework and run in plaintext mode (which would also remove OpenSSL fork BoringSSL from causing maintenance headaches because of upstream flaws).
For very high latency / low bandwidth services (ie mission to mars), one would think about RPC using a transport like SMTP (ie Active Directory alternate replication) or MQTT (ie Facebook Messenger, ZigBee, SCADA)
Bonus (off-topic): It would be nice if gRPC had alternate pluggable transports like ØMQ (which also itself supports UNIX sockets, TCP, PGM and inproc), because HTTP/2 isn't stable in all languages yet and it's slower than ØMQ. And, it's worth looking at nanomsg (especially in the HFT world) because it could be extended with RDMA/SDP/MPI and made crazy low-latency/zero-copy/Infiniband-ready.
I am working on a project which involves real time chat (messaging, including group chats).
I have worked with websockets before, So I started working on this using spring-websockets and I did some reading about what is the best way to implement it. Then I came across STOMP (as a sub-protocol for websockets)and as there is direct support for STOMP in spring it was bit easy to achieve what I was supposed to do.
But my doubt is as far as my understanding STOMP and XMPP are similar protocols(messaging protocols) but I could not find any questions/blogs where the differences are explained and why somebody would prefer one over another?
It will be really helpful if somebody explains how these two protocols differ?
Thank you.
As the successor of Jabber, XMPP is more focused on instant messaging instead of STOMP. XMPP is an extensible protocol and could be used for other purposes, but there are plenty of built-in mechanism and implementations regarding IM. STOMP offers a more general mechanism and "message" here refers a broad meaning.
Let's say you choose STOMP for your project. Then you will probably need to define basic messages for certain scenarios (peer-to-peer, group chat) which are already offered by XMPP.
To compare two protocols;
STOMP message is carried as plain text (as its name indicates) whereas XMPP is structured as XML.
STOMP connections can be established via TCP or WebSockets. XMPP supports TCP or HTTP (WebSocket standard is also propopsed).
In Java world, Spring has the ability to talk STOMP and it's very easy to implement. However, XMPP support can be added by adding 3rd Party APIs (i.e. Smack)