What is the mechanism of grpc server side pushing? - grpc

While I'm writing a service with grpc, I'm trying to compare http/2 with websocket by server side pushing mechanism.
I know for websocket, the client will send a request with Upgrade: WebSocket and Connection: Upgrade headers to server and establish the long-lived connection. Then server will send the data freely after the connection is established.
But for grpc, as it is routed upon http/2, from the wiki page, https://en.wikipedia.org/wiki/HTTP/2_Server_Push, it says the server would need to predict the potential requests the client would send, and send a PUSH_PROMISE frame as early as possible.
Here are my two questions:
Does it mean that the server would also need to receive a corresponding response(request) from client in response to this PUSH_PROMISE header to decide if client wants to receive or decline the certain push?
In Grpc, if I have a sever side streaming, say send a message every 1 second from server. Does it mean the server need to send a PUSH_PROMISE to client every 1 second or at least before every data frame that server pushes to client?

gRPC does not currently support/use PUSH_PROMISE.
Streaming RPCs in gRPC use HTTP/2 streams; the entire RPC is contained in a request/response in HTTP. The main difference is that HTTP/2 implementations generally allow such streams to be streaming and bidirectional (the client can send more in the request after reading part of the response), while in HTTP/1 that was hit-or-miss.
In gRPC the client will always initiate the RPC. But for server-streaming the server can then reply with multiple messages over time via the stream. This would be similar to the scenario you described with websockets.

Related

Mixing websockets and http

When speaking from a conceptual point of view, is it standard practice to mix WebSockets and HTTP requests when making a chat application (or any application that requires real-time communication between devices)?
Imagine a scenario with a client and a server in a chat app. What would be the best approach for connecting and sending data between the client and the server? Would it be using sockets for both sending and receiving or HTTP requests for sending (so the client would get a response and then know if the message was received), and then using WebSocket for only receiving new messages?
No this is not standard practice.
If you need real-time communication between client and server you normally just use a websocket connection and keep that one open. The client can send messages to the server and receive messages through the same connection.
Using HTTP requests for sending messages to the server and receiving new messages via websocket seems odd and just adds unnecessary complexity.
Now if your server has some endpoints to subscribe for real-time data e.g. a chat room and endpoints for getting information you don't necessary want to subscribe to e.g. information about a certain user, than you can use the appropriate protocol for each endpoint

Apache Camel TCP client with Permanent connection to a TCP server Asynchronous response

I need to implement a tcp/ip client which connects to existing tcp server with a permanent connection. the client has to send multiple requests and response arrives asynchronously. I have use netty to do the integration part. I have to ensure that the response is done for the relevant request. How to implement this using apache camel.
rest()
.consumes("application/json").produces("application/json")
.post("/tcp")
.type(RequestBean.class)
.route()
.process(this::transformTcpMessage)
.to("netty://tcp://127.0.0.1:9898")
.endRest();
This is What I need to achieve. this TCP client need to have a permeant connection and server may response asynchronously. So I need to make sure that the relevant response has been send to the relevant request.

Persistent (push-based) communication with HTTP

Consider the following diagram (source). The diagram describes an HTTP Push model with multiple events pushed to the client over a persistent connection.
How does one establish a persistent connection in HTTP?
How could the server push events to the client over this connection? To my knowledge, only the client (e.g. browser) can initiate HTTP requests.
I can see this working with a WebSocket (full-duplex long-lived connections) but to my knowledge, they don't go over HTTP.

Why and how SSE (Server-Sent Events) are unidirectional

https://developer.mozilla.org/en-US/docs/Web/API/EventSource
The EventSource interface is web content's interface to server-sent events. An EventSource instance opens a persistent connection to an HTTP server, which sends events in text/event-stream format. The connection remains open until closed by calling EventSource.close().
From what I understand server-sent events require persistent HTTP connection (Connection: keep-alive) so similarly to keeping the connection alive like in case of web sockets.
If the connection is persistent, why server-sent events are unidirectional? Web socket connections are persistent as well.
In this case, what happens if I send a request to my HTTP service and I have persistent connection opened due to EventSource. Will it re-use HTTP connection opened by EventSource or open a new connection?
If it re-uses the connection opened by EventSource how is it considered unidirectional?
Might be trivial, but I had to ask because it is not clear. Because nothing mentions what happens to subsequent HTTP requests when there's existing connection opened by EventSource.
For example, it seems possible to me to implement centralized chat app using SSE:
User 1 sends message to User 2(by sending it to HTTP server). Server sends event to user 2 with a new message, user 2 sends another request to HTTP server with message for User 1, server sends event to user 1.
How is that not considered bi-directional?
Related:
What's the behavioral difference between HTTP Stay-Alive and Websockets?
SSE is unidirectional because when you open a SSE connection, only the server can send data to the client (browser, etc.). The client cannot send any data. SSE is a bit older than WebSockets, hence may be the difference between the unidirectional and bi-directional support between these two technos.
In your use-case, if you open a SSE connection (which is an HTTP connection), only the server will be able to send data. If you wish to send a request to your HTTP service, you will need to open a new "classical" HTTP connection. You will see your browser opening two HTTP connections: 1 for the SSE connection and 1 for the classical HTTP request (short live).
You can implement a chat with SSE. You can have a SSE connection (hence HTTP) to let the user receives the messages from the server. And you can use POST HTTP requests to enable the user to send his/her messages.
Note that most of the browsers can open around 6 HTTP/1.x connections to the same host. So, if you use 1 SSE connection, it will remain potentially 5 HTTP/1.x connections. This is only true with HTTP/1.x. With HTTP 2.x, the connections to the same host are multiplexed: so, in theory, you can send as many HTTP requests at the same time as you wish or you can open as many SSE connections as you wish and thus, by passing the limitation of the 6 connections.
You can have a look at this article (https://streamdata.io/blog/push-sse-vs-websockets/) and this video (https://www.youtube.com/watch?v=NDDp7BiSad4) to get an insight about this technology and whether it could fit your needs. They summarize pros & cons of both SSE and WebSockets.

how does the HTTP protocol behind client/server communication works?

HTTP is client - server communication where client always initiates the connection and server responds.
In the client server communication with HTTP 1.1 the following steps takes place:
1. Client sends the request to the server.
2. Server sends the response to the client with the response message and the status code.
My question is how is the data transfer handled in the protocol? I know HTTP is stateless and also it is either everything or nothing mechanism but how do you prove this? How is the handshake between server and client?
For example: When the server sends the response back to the client, what happens if 50% of the data is sent and then there is connection loss...then what will happen in this scenario? Will the client wait for remaining 50% of the message or it will start new transfer where server tries to send 100% of the message again? (In synchronous communication)
HTTP relies on a TCP connection, so in your example if 50% of the data is correctly sent but others packets (yes, you should think in terms of packets) are lost, the data will be sent again following the rules defined in TCP protocol

Resources