I am thinking about using a gRPC service to facilitate notifications between two services. (as an aside, I will be using protobuf-net/ protobuf-net.Grpc) The intent is that the client service would establish and maintain a connection to the server service, and react to notifications over time. In an perfect technology world where there are no network blips, no server restarts, etc the idea would be to establish this connection once and have that server streaming call live for the lifetime of the application. Obviously in the real world we need to deal with retries, reconnects, fail-overs etc.
My question is: Is calling a server streaming call in grpc and keeping the call open for long periods of time an appropriate use of server streaming calls, or is it an abuse of that feature?
This is a perfectly fine use case for gRPC. gRPC is designed for this kind of use.
Yes, you have to deal with reconnections or more exactly reestablishment of streams when the connection to the server dies.
Related
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
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.
I'm evaluating some messaging libraries and protocols (e.g. ZeroMQ, WAMP). One of my main requirements is that sending messages from client to server and vice verse (two way communication) must be absolute safe with respect to client/server crashes. This means to me that e.g. the client must continue sending all not delivered messages after a spontaneous reboot. So the library should implement some kind of file based buffering. Is there anything there I can use out of the box?
[EDIT]
Some note on my use case:
In my scenario there are around 1000 clients communicating with one server. There is no direct client to client communication required. But I need a two-way communication, so both, the clients can push some data to the server and vice versa. The clients are connected via 3G mobile network. Both, client and server are written in C#. I focused on using ZeroMQ, Apache Thrift or WAMP. But one of the main requirements is to ensure asynchronous but safe messaging with respect to system crashes. So when the client starts an asynchronous data push to the server, and it will crash before the message can be delivered to the server, it is required that the client will continue sending the message after a reboot.
You might look into the Apache.org's Kafka project.
The problem is harder than it looks, and most people don't want to pay the price to make it happen.
Also, there is a UX issue with old queued up messages replaying without the user's understanding.
I am new to Websockets. While reading about websockets, I am not been able to find answers to some of my doubts. I would like if someone clarifies it.
Does websocket only broadcasts the data to all clients connected instead of sending to a particular client? Whatever example (mainly chat apps) I tried they sends data to all the clients. Is it possible to alter this?
How it works on clients located on NAT (behind router).
Since client server connection will always remain open, how will it affect server performance for large number of connections?
Since I want all my clients to get real time updates, it is required to connect all my clients to server, so how should I handele the client connection limit?
NOTE:- My client is not a Web browser but a desktop application.
No, websocket is not only for broadcasting. You send messages to specific clients, when you broadcast you just send the same message to all connected clients, but you can send different messages to different clients, for example a game session.
The clients connect to the server and initialise the connections, so NAT is not a problem.
It's good to use a scalable server, e.g. an event driven server (e.g. Node.js) that doesn't use a seperate thread for each connection, or an erlang server with lightweight processes (a good choice for a game server).
This should not be a problem if you use a good server OS (e.g. Linux), but may be a limitation if your server uses a desktop version of Windows (e.g. may be limited to 200 connections).
I am using a WCF service to administer a windows service running on a remote machine. We have an administration client we use for modifying the windows service configuration, as well as monitoring the state of the service in real-time. For the real-time monitoring, we poll the service for it's state every second.
Currently, we are leaving the client connected all the time while monitoring the service but I continually read that it is recommended to connect and disconnect for each call, much like you would for a database.
Would it be recommended in our situation where we are making frequent calls to the service, or would connecting and disconnecting add too much overhead to the process?
Thanks
By default and as a recommended best practice, you're using the per-call activation in WCF, e.g. each request to your WCF service gets a new instance of a service class, that instance handles your request, returns a result, and then is disposed.
In this case, I don't really see any point in constantly breaking and re-establishing the communication channel (e.g. constantly disposing and re-creating the proxy client). There's nothing on the WCF service side that "lingers around" in memory and takes up resources or anything like that. Also, contrary to most databases, there's usually no "per-connection" licensing or anything involved, either.
What you need to be able to deal with in this scenario would be a situation where your communication channel goes into "faulted state", e.g. when something bad happens - when the service call fails and throws an exception, or when a network fluke causes your channel to break. In such a case, you need to have recovery mechanisms on your client side to handle this and re-establish the connection again.
The situation might be a bit different if you have session-oriented WCF services - but those should definitely be the exception, and only used when needed by all means.