Ktor 2 seems to have made it easier to implement server plugins, but they don't mention client plugins at all in their documentation (as far as I can see). What is the easiest way to intercept a http request+response in the ktor2 client that allows me to store a bit of state when the request is made and access that state when the response is available?
Related
I am beginning to integrate WebSockets into my app for live updates, and it has lead me to wonder whether I should eliminate HTTP requests from the app altogether.
The downsides I have found so far would be:
Harder to split my back-end into MicroServices in the future.
Harder to expose an API to third party software in the future.
Harder to perform caching and background sync on post requests.
How would I achieve these things with WebSockets?
Also, how reliable is data received through WebSockets? Can I be sure the data is consistent? Can I be sure data I send gets processed correctly? Does it make sense to send "GET" requests through WebSockets?
Opening extra HTTP requests when I have an open WebSocket seems wasteful, but I have so many doubts and questions when it comes to eliminating HTTP.
I am creating an application(Nuxtjs) and am having troubles determining a good approach for sending data to the API(expressjs) and retrieving real-time updates. It seems that i can create "bi-di" connections with both protocals [Server Sent Events(SSE) and Axios or Websocket(WS)].
Both technologies work with most of the browsers, so i do not see a need to add additional libraries such as socket.io - For those individuals that do not have a current browser (too bad).
The application is based on user input of form data/clicks. Other users are then notified/updated with the information. At which point, the user can respond and the chain goes on(Basic chat like flow some information will be exchanged quickly while some may not or ever).
In my experience, the user flow would rely more heavily on listening for changes than actually changing the data - hence why i'm considering SSE. Unfortunately, both protocols have their flaws.
Websockets:
Not all components will require a WS to get/post information as such it doesn't make sense to upgrade a basic http connection at the additional server expense. Therefore another method other than WS will be required(Axios/SSR). Example: Checking to see if a user name exists
Security firewalls may prevent WS for operating properly
express-ws makes sockets easy on the API end
I believe you can have more than 6 concurrent connections by one user (which may be pro and con)
Server Sent Events
Seems like the technology is fading in favor of WS
Listening to the events seem to be as easy as listening to events for WS
No need to upgrade the connection but will have to use node-spdy within the expressjs API - This may also be a good implementation for WS due to multiplexing
Little more backend code to setup http2 and emit the SSEs(Ugly code as well - so functions will be made)
Limited to HTTP limitations (6 concurrent connections) which is a problem as the users could easily max this out(ie. having multiple chat windows open)
TLDR
The application will be more "feed" orientated with occasional posting(which can be handled by Axios). However, users will be listening to multiple "feeds" and the HTTP limitations will be a problem. I do not know what the solution would be because SSE seem like the better option as i do not need to continually handshake. If this handshake is truly inconsequential(which from everything i have read isn't the case) than WS is likely a better alternative. Unfortunately, there is soooo much conflicting information regarding the two.
Thoughts?
SSE, Web Sockets, and normal HTTP requests (via AJAX or Fetch API) are all different tools for different jobs.
SSE
Unidirectional, from server to client.
Text-based data only. (Anything else must be serialized, i.e. JSON.)
Simple API, widely compatible, auto-reconnects, has built-in provision for catching up on possibly missed events.
Web Sockets
Bi-directional.
Text or binary data.
Requires you to implement your own meaning for the data sent.
Standard HTTP Requests
Client to Server or Server to Client, but only one direction at a time.
Text or binary data.
Requires extra effort to stream server-to-client response in realtime.
Streaming from client-to-server requires that the entire data be known at the time of the request. (You can't do an event stream, for example.)
How to decide:
Are you streaming event-like data from the server to the client? Use SSE. It's purpose-built for this and is a dead simple way to go.
Are you sending data in only one direction, and you don't need to spontaneously notify clients of something? Use a normal HTTP request.
Do you need to send bidirectional data with a long-term established connection? Use Web Sockets.
From your description, it sounds like either SSE or Web Sockets would be appropriate for your use case. I'd probably lean towards SSE, while sending the random API calls from the client with normal HTTP requests.
I do not know what the solution would be because SSE seem like the better option as i do not need to continually handshake. If this handshake is truly inconsequential(which from everything i have read isn't the case) than WS is likely a better alternative.
Keep in mind that you can simply configure your server with HTTP keep-alive, making this point moot.
I personally avoid using websockets as a 2-way communication between client and server.
I try to use sockets to broadcast data from server to users or a single user(socket), so they can get real-time updates, but for the post requests from client to server I tend to use axios or something similar, because I don't want to pass sensitive data (like access keys etc) from client to server.
My data flow goes something like
User posts data to the server using axios, SSE or whatever
Backend server does what it has to and notifies socket that an event has occured
Socket server then notifies who he has to
My problem with using sockets to send data from client to server is the authentication issue. Technically, you can't pass anything that is not available to client-side javascript through a socket, meaning that to authenticate the action you will have to send sensitive information through a websocket. This is an issue for multiple reasons - if your sensitive data can be accessed using client-side js, there is a bunch of attacks that can be done here. Also someone can listen to the communication between ws and client. This is why I use API calls (axios etc) and store sensitive data to http-only cookies.
So once server wants to notify the user that something has happened, you can easily do that by telling the websocket server to send the data to the user.
You also want to keep your API server stateless, meaning no sockets in your API. I use separate server just for websocket connections, and my API server and websocket server communicate using redis. Pub/sub is a really neat feature for internal server communication and state management.
And to answer your question regarding multiple connections - you can use a single connection between your websocket server and client, and broadcast data using channels. So one channel would be for notification feed, other channel could be for story feed etc.
I hope this makes sense to you. This stack has worked really good for me.
I have just began using socket.io and I have some experience with express. I know socket.io has bidirectional communication while express is only client to server.
This made me think, why don't we just use socket.io with different namespaces and not use express at all?
In which cases should I use socket vs express?
In the case I need bidirectional communication, is it advisable to make the client -> server with express and then use socket for server -> client?
First off express and socket.io are pretty different things. Express is a full-blown web server framework. You use it for setting up a web-site, fielding http requests from a browser, fielding http requests for an API, etc...
socket.io is a communication layer that sits on top of the webSocket protocol and the webSocket protocol uses an http server to establish its initial connection. While there is a little bit of overlap between what you can do with socket.io and Express, they are more different than they overlap.
For example, if you're setting up a web-site, you couldn't do that with socket.io, one would use something like Express.
Now, if you have a specific programmatic need to communicate between an arbitrary client and a server, you have a zillion choices. If the client is in a browser and the programmatic interface is from Javascript in the browser, then you have fewer choices.
From the browser, using http ajax requests via Express is one choice. Setting up a socket.io connection and defining you own messages is another choice.
Reasons to pick socket.io over Ajax calls to Express from browser Javascript:
You need/want two-way communication over the same channel.
The client is sending a lot of requests to the server (the overhead for sending a socket.io message is lower than an ajax call, once the socket is already set up, so if you're sending a lot of messages, then socket.io messages are more efficient than http requests)
Reasons to pick Ajax calls to Express:
HTTP connections are stateless and short-lived which can make implementing high scale, multi-server implementations with failover and redundancy easier.
There are a wealth of tools to use for http connections from authentication libraries to data formats (MIME) to audio to video, etc...
You want your client to run in places where a long-connected socket.io during inactive periods of time may not be practical (perhaps mobile or battery operated devices).
You want to run in situations where there are proxies, firewalls or other network infrastructure that may not support long running webSocket connections or specifically disallow them.
You want a request/response model. HTTP is request/response where you get a specific response for each request and you know exactly which response goes with which request.
So, as you can see, there is no generic answer to this question. It really depends upon the specific of your communication, the interoperability you desire and the exact needs of your code.
Here are some other references on this topic:
Ajax vs Socket.io
Websocket vs REST when sending data to server
Using AJAX vs. socket.io socket messages
websocket vs rest API for real time data?
So far all the guides i have looked at involve communicating with a frontend client via Graphql, I wonder does it have any usage for something purely backend, such as communicating among microservices?
You can certainly make a request to the API from another server as well. Just as you can make a call to any REST endpoint from anywhere, you can perform server to server communication with GraphQL APIs as well.
For example, at Scaphold, we use Lambda for many webhooks and scheduled tasks. And from our microservice, we use the request library to make POST requests to the Scaphold server's GraphQL API.
Here's an example of a create mutation that you can use from a Node server.
Hope this helps!
I have a service that always returns the same results for a given parameter. So naturally I would like to cache those results on the client.
Is there a way to introduce caching and other effect inside the WCF pipeline? Perhaps a custom binding class that could site between the client and the actual HTTP binding.
EDIT:
Just to be clear, I'm not talking about HTTP caching. The endpoint may not necessarily be HTTP and I am looking at far more effects than just caching. For example, one effect I need is to prevent multiple calls with the same parameters.
The WCF service can use Cache-Control directives in the HTTP header to say the client how it should use the client side cache. There are many options, which are the part of HTTP protocol. So you can for example define how long the client can just get the data from the local cache instead of making requests to the server. All clients implemented HTTP, like all web browsers, will follow the instructions. If your client use ajax requests to the WCF server, then the corresponding ajax call just return the data from the local cache.
Moreover one can implement many interesting caching scenarios. For example if one set "Cache-Control" to "max-age=0" (see here an example), then the client will always make revalidation of the cache by the server. Typically the server send so named "ETag" in the header together with the data. The "ETag" represent the MD5 hash or any other free information which will be changed if the data are changed. The client send automatically the "ETag", received previously from the server, together inside the header of the GET request to the server. The server can answer with the special response HTTP/1.1 304 Not Modified (instead of the typical HTTP/1.1 200 OK response) and with the body having no data. In the case the client will safe to get the data from the local cache.
I use "Cache-Control:max-age=0" additionally with Cache-Control: private which switch off caching the data on the proxy and declare that the data could be cached, but not shared with another users.
If you want read more about caching control with respect of HTTP headers I'll recommend you to read the following Caching Tutorial.
UPDATED: If you want implement some general purpouse caching you can use Microsoft Enterprise Library which contains Caching Application Block. The Microsoft Enterprise Library are published on the CodePlex with the source code. As an alternative in .NET 4.0 you can use System.Runtime.Caching. It can be used not only in ASP.NET (see here)
I continue recommend you to use HTTP binding with HTTP caching if it only possible in your environment. In the way you could save many time of development and receive at the end more simple, scalable and effective application. Because HTTP is so important, one implemened already so much useful things which you can use out-of-the-box. Caching is oly one from the features.