How to get number of Max_concurrent_streams and stream id in http2 clients like okhttp or java 11 httpclient - okhttp

I am having below requirements with respect to http2.
1) While intiating client side http connection, I should be able to set Max_concurrent_streams supported by http2 server, and handle failure conditions accordingly.
2) Get stream ID of stream and assign priorities.
I checked okhttp client and Java11 http client. But couldnt find any way to achieve the same.
Please let me know is there any way to achieve these.

If you need to deal with low-level details of the HTTP/2 protocol, you can use Jetty's HTTP2Client.
Note that it's the server that decides the max number of concurrent streams it can support, and the client cannot modify that value.
The client can send to the server the max number of concurrent streams it supports, but that number refers to the pushed streams that the server can send to the client.
Using the HTTP2Client APIs you will have easy access to the stream id and will be able to send to the server PRIORITY frames to assign (and modify) priorities to requests.
This is a simple example of how to use HTTP2Client.
You can find more examples in this directory.

Related

How does grpc achieve "bidirectional streaming rpc" like a websocket?

Is this bidirectional stream native to http2? I looked at various http2 client. I couldn't find any example where it allows the client and server to establish a single connection and continuously push messages from both side.
(For http2 maybe on a lower level, the communications between client/server just had one tcp connection and all the request/responses are multiplexed in it, but from application level can't find any example where you establish a single connection object, and that connection object can be reused to push messages to each other).
So how did grpc achieve "Bidirectional streaming RPCs"? Specifically in this document
https://grpc.io/docs/what-is-grpc/core-concepts/
It indicates that the server side could define a Bidirectional streaming RPC, and it allows both the client and server side to continuously push messages, and achieve features that is websocket like.
Yes, bidirectional streaming is native to HTTP/2. You can read RFC-7540 for the details of how the protocol works, but basically it allows you to create several streams on a single TCP connection, and each stream can send data in either direction independently of each other.
I'm not familiar with all of the HTTP/2 libraries out there, but I know that nghttp2 will allow this in C++, and I think Java and Go have HTTP/2 implementations in their standard libraries.

wanted - golang wrapper around Dial/Listen to handle tcp server/client communication

In golang, when you make a client/server combination with Listen/Accept on the server and Dial on the client, as far as I can tell writing to the client doesn't actually guarantee the full transmission chain. IE when you say:
_len, _err := conn.Write([]byte("sent"))
it is possible that the text you send may reach the buffer of the client machine but not the client itself. In other words, if the client becomes unavailable, _err may still be unset and _len may still show the correct length of bytes being sent. I noticed this by killing the connection between my server and client and monitoring the return status of conn.Write() manually and seeing that it didn't show an error.
In other words, just using these tools out of the box won't guarantee delivery, and I was hoping that there was a go library that implemented a client acknowledgement to insure this further guarantee. I'd like to say something like:
_len, _err := _write(conn, "sent\n")
and have guarantees that if the client goes away that _err will be set accordingly - assuming a specific timeout between the send and an acknowledgement from the client.
Is there a standard library like this? I could write my own wrapper to do this, but I have a feeling the logic to do this correctly would be somewhat intricate.
thanks much again for any info,
Ed
Is there a standard library like this?
There is no standard library for this. How application level acknowledgements are done is specified in the specific application protocol, i.e. a protocol like HTTP (web), SMTP (mail delivery), SIP (VoIP) etc. And this protocol must be spoken in both client and server. There is no way for a client to enforce some application level acknowledgement if it is not part of the protocol specification and the server will not explicitly send it.
Therefore you either need to pick an application protocol which supports the semantics you need and use it on both client and server. Or you need to define your own application protocol which supports the exact semantics you need and implement it yourself on both sides.

How to use Strimzi Kafka Bridge as a streaming service

Using CNCF's Strimzi Kafka Bridge I have created a small API that can interact with Kafka server using a HTTP/1.1 protocol. This is all good for a request-response scenario. However, my requirement is to stream events received on the Kafka topic to the subscribed client(s) (through the Strimzi bridge) as soon as I receive them preferably on a long lived HTTP connection (as per my understanding). It's a waste of client resources to continuously poll the bridge for messages and come back empty handed. I would like the Kafka server stream these events to the client directly.
I am a little unsure about SSE or Websockets or long polling. I did quite a bit of reading on these methodologies to stream data to the client. However, I am unable to figure out if these changes are at the communication or the application layer or both.
Do you just build an API (irrespective of the technology) using a traditional HTTP communication protocol and somehow upgrade it to use Websockets OR use of Websockets should be embedded in your application libraries ground up?
I can provide more information if needed. The Strimzi Kafka bridge website does not mention anything about "server side streaming" OR maybe I am misunderstanding the real purpose of the tool.
The Strimzi Kafka HTTP bridge is meant as a "translator" for HTTP to Kafka native protocol and vice versa. It means that the HTTP client has to have the same behavior as a native Kafka client so, in the case of a consumer, doing a poll for getting messages which is how Kafka works natively. Imho HTTP 1.1 is not for streaming at all.
Websockets is a completely different protocol to which you can upgrade of course starting from an HTTP connection but it's not supported by the Strimzi bridge.
Actually, the AMQP 1.0 protocol which is in the bridge (as a POC) can support this kind of scenario so establishing a connection and having the bridge pushing on that connection instead of polling from the client side.
#Nick thinking more, actually you can do "long polling". The GET on the /records endpoint for getting messages has a timeout parameter on the query string. Its value is used as timeout for the internal native Kafka poll in the bridge. It somehow provides you the long polling behaviour because the poll doesn't return until there are available records or the timeout expires. If you set a high timeout, you can have the behavior you want avoiding polling more times with opening/closing more HTTP connections for that.
More details on the timeout parameter here:
https://strimzi.io/docs/bridge/latest/#_poll

The theory of websockets with API

I have an API running on a server, which handle users connection and a messaging system.
Beside that, I launched a websocket on that same server, waiting for connections and stuff.
And let's say we can get access to this by an Android app.
I'm having troubles to figure out what I should do now, here are my thoughts:
1 - When a user connect to the app, the API connect to the websocket. We allow the Android app only to listen on this socket to get new messages. When the user want to answer, the Android app send a message to the API. The API writes itself the received message to the socket, which will be read back by the Android app used by another user.
This way, the API can store the message in database before writing it in the socket.
2- The API does not connect to the websocket in any way. The Android app listen and write to the websocket when needed, and should, when writing to the websocket, also send a request to the API so it can store the message in DB.
May be none of the above is correct, please let me know
EDIT
I already understood why I should use a websocket, seems like it's the best way to have this "real time" system (when getting a new message for example) instead of forcing the client to make an HTTP request every x seconds to check if there are new messages.
What I still don't understand, is how it is suppose to communicate with my database. Sorry if my example is not clear, but I'll try to keep going with it :
My messaging system need to store all messages in my API database, to have some kind of historic of the conversation.
But it seems like a websocket must be running separately from the API, I mean it's another program right? Because it's not for HTTP requests
So should the API also listen to this websocket to catch new messages and store them?
You really have not described what the requirements are for your application so it's hard for us to directly advise what your app should do. You really shouldn't start out your analysis by saying that you have a webSocket and you're trying to figure out what to do with it. Instead, lay out the requirements of your app and figure out what technology will best meet those requirements.
Since your requirements are not clear, I'll talk about what a webSocket is best used for and what more traditional http requests are best used for.
Here are some characteristics of a webSocket:
It's designed to be continuously connected over some longer duration of time (much longer than the duration of one exchange between client and server).
The connection is typically made from a client to a server.
Once the connection is established, then data can be sent in either direction from client to server or from server to client at any time. This is a huge difference from a typical http request where data can only be requested by the client - with an http request the server can not initiate the sending of data to the client.
A webSocket is not a request/response architecture by default. In fact to make it work like request/response requires building a layer on top of the webSocket protocol so you can tell which response goes with which request. http is natively request/response.
Because a webSocket is designed to be continuously connected (or at least connected for some duration of time), it works very well (and with lower overhead) for situations where there is frequent communication between the two endpoints. The connection is already established and data can just be sent without any connection establishment overhead. In addition, the overhead per message is typically smaller with a webSocket than with http.
So, here are a couple typical reasons why you might choose one over the other.
If you need to be able to send data from server to client without having the client regular poll for new data, then a webSocket is very well designed for that and http cannot do that.
If you are frequently sending lots of small bits of data (for example, a temperature probe sending the current temperature every 10 seconds), then a webSocket will incur less network and server overhead than initiating a new http request for every new piece of data.
If you don't have either of the above situations, then you may not have any real need for a webSocket and an http request/response model may just be simpler.
If you really need request/response where a specific response is tied to a specific request, then that is built into http and is not a built-in feature of webSockets.
You may also find these other posts useful:
What are the pitfalls of using Websockets in place of RESTful HTTP?
What's the difference between WebSocket and plain socket communication?
Push notification | is websocket mandatory?
How does WebSockets server architecture work?
Response to Your Edit
But it seems like a websocket must be running separately from the API,
I mean it's another program right? Because it's not for HTTP requests
The same process that supports your API can also be serving the webSocket connections. Thus, when you get incoming data on the webSocket, you can just write it directly to the database the same way the API would access the database. So, NO the webSocket server does not have to be a separate program or process.
So should the API also listen to this websocket to catch new messages
and store them?
No, I don't think so. Only one process can be listening to a set of incoming webSocket connections.

Which is better: multiple web socket endpoints or single web socket endpoint in Java EE7

Java EE 7 allows you to create new endpoints very easily through annotations. However, I was wondering is having multiple endpoints one to handle each message type a good idea or should I have just one endpoint facade for everything?
I am leaning towards having one single end-point facade based on the theory that each endpoint creates a new socket connection to the client. However, that theory could be incorrect and Web Socket may be implemented so that it will use just one TCP/IP socket connection regardless of how many web socket end points are connected so long as they connect to the same host:port.
I am asking specifically for Java EE 7, as there may be other web socket server implementations that may do things differently.
Just noticed an ambiguity on my question re: message types. When I say message types I meant different kinds of application messages not native message types such as "binary" or "text". As such I marked #PavelBucek answer as the accepted one.
However, I did try an experiment with Glassfish and having two end points. My suspicions were correct and that there is a TCP connection established per connected endpoint. This would cause more load on the server side if there is more than one websocket endpoint being used on a single page.
As such I concluded that there should be only one endpoint to handle the application messages provided that everything is a single native type.
This would mean that the application needs to do the dispatching rather than relying on some higher level API to do it for us.
The only valid answer here is the latter option - having multiple endpoints.
See WebSocket spec chaper 2.1.3:
The API limits the registration of MessageHandlers per Session to be one MessageHandler per native websocket message type. [WSC 2.1.3-1] In other words, the developer can only register at most one Mes- sageHandler for incoming text messages, one MessageHandler for incoming binary messages, and one MessageHandler for incoming pong messages. The websocket implementation must generate an error if this restriction is violated [WSC 2.1.3-2].
As for using or not using multiple TCP connections - AFAIK currently there will be new connection for every client and there is no easy way how you can force anything else. WebSocket multiplexing should solve it, but I don't think any WebSocket API implementation support it (I might be wrong..)

Resources