Should I use WebSocket for this use case - javascript

I kind of new for WebSocket and would like to ask you guys a question if WebSocket is really the best way I should go.
Use case. Clients need to submit different kinds of jobs, e.g. J1, J2, J3, ... to server API through web GUI and the server will do or distribute to other computational resources to accomplish the jobs, however the server needs to update each Client the progress of the jobs they submit. One very simple example is that, if Client A wants to upload a big file, and server needs to notify the progress of the uploading until it is fully uploaded. I do think this is a very common use case.
The way I am doing now is to use HTTP polling, i.e. query status from Client side every 1s to get status from the server and display. I do think there must be other more efficient way of doing this, and I come up with WebSocket way. However after doing some reading, WebSocket's best use is to real-time broadcast same data to all subscripters, e.g. updating a certain stock price in a given channel.
Do you guys think if WebSocket is the right way to go? if so, how should I build the channel for different Clients and different types of jobs, or any other suggestions?
thank you.

WebSocket may be a solution if you require real-time notification. You don't need different channels for each job, you just need messages that allow you to multiplex on server-side and demultiplex on client-side.
You should take into account that each opened WebSocket uses resources on the server, so you should consider the average workload.
On the other hand, if you don't require real-time notifications, loose polling may be a better solution.

Related

Server Sent Events filtering on frontend side

I ve got the following situation:
Multiple users may concurrently establish a connection through a Javascript-based frontend to my Java-based backend service. Afterwards, the Java backend may gather messages from a queue and needs to inform the respective user of a "business event" related to a certain business case read from the queue. But only a subset of the users should be notified by a Server Sent Event (SSE).
Currently, I'm polling the backend regularly to know if for the respective business cases I am looking at, e.g. with ID A, B, C etc. will have new data that needs to be shown to the user. This is super inefficient and I was thinking about using SSEs as an alternative.
Since I don't want to introduce session handling at all, i will have to filter all the incoming events according to the case id (A, B, C, ... ) on the frontend side, but essentially any frontend that established a connection may read all events published.
While above scenario might be ok for certain use cases, what if the SSE contained sensitive information, e.g. private/personal data that User 1 should receive, but User 2 or 3 should not see at all in their browsers while inspecting deeper? Filtering on the frontend seems super bad in this case.
Am i misusing SSE here? Are there better alternatives to inform the frontend about changes in backend?
Based on the proposed ideology, your data can be handled on either side. Although handling business logic in the client, isn't the best idea, I've seen quite a few cases in which the backend developer doesn't like, nor is interested in, handling some of the business-related logic, thus the only possible solution is to handle them in the frontend.
In a case that the data (in your case, events) might contain confidential information, there are at least four possible options (excluding the (long-)polling mechanism):
Session Management in the Backend
This option is pretty self-explanatory, you must create some sort of
session management in the backend to keep track of who's who, thus
being able to send the proper events to the right person.
Creating a middle-man to handle such information
Although this isn't the cleanest solution, if you're not the person in charge of the backend, and he isn't helping you in your case, it's better not to screw the security of the users and create a middle-man webserver (which means you have to manage the sessions as well).
Using encryption
In theory, it's possible to create an encryption protocol in which only the right client, with the appropriate private key, can decode the message. However, the implementation of such a mechanism requires a lot more code, and at its best can reduce the headache of creating a complex (and usually, dynamic) session handling infrastructure.
Don't do anything
In case you're forced to complete the feature as soon as possible, just create something that works, but be sure to try replacing it with a proper implementation before it hits the production branch.
Probably, it's one of the most abstract answers that I've written on StackOverflow, but hopefully, it can help you to handle this situation more gracefully.
Figured out the answer myself. If I want to keep information private, I should never send any information out to the frontend(s) and rather filter out on the backend side beforce sending events out.
Opening the connection may be done in a parametrized way, e.g.
on path /sse/{id} and on the backend side, when handling this connection, while reading the user-information from the established connection, the backend should simply not publish any information on this channel.

How to implement horizontall scalability using NodeJs

So, I've web application which structure is based on this file structure: https://scotch.io/tutorials/setting-up-a-mean-stack-single-page-application .
My app also has a connection to mongoDB on Mlab.
what my app does:
allows users to login/signup;
retrieves data from mlab;
retrieved data can be rated by users;
retrieved data can be deleted by admin;
users can add data to db (data is training plans);
Now I need to make my app horizontally scalable, but I am a bit lost here:
•Sine I assume there i no real-time activities I shoudn't need something like socket.io?
•Should I add some sort of MQ (rabbitMQ, ZMQ, etc.): If so, perhaps any pointers on how to, because most of the examples just use simple text messages.
•I am quite sure I would need some load balancer. Nginx, HaProxy... I probably should change my express server setup to listen to multiple ports first, is that right?
Or am I completely wrong about this?
P.S.: Hope this isn't too broad question.
Different needs require different approaches :)
These can vary according to your needs. Not every scalable application has to have them.If you want the application to be asynchronous, you can take all the requests in a queue and return to the client instantly.You may then need a push mechanism to notify the client that the operation is over. (Socket.io, RabbitMQ etc)
Of course you will need a reverse proxy to distribute requests to different servers load balanced or workload basis (HAProxy etc.)
The first thing you need to pay attention to when you want to scale the application is to have a stateless structure.Or get them out of the process.(For example session, cache, file server)The second thing you need to be aware of is the authentication phase.A client that logged in from ServerA may encounter "unauthorized" on ServerB on subsequent requests.You should also think about the resources used by the application.While these resources serve a single server, they will begin to respond to millions of requests from five to ten servers simultaneously.There are things like monitoring instances.And a lot of things like that.
These are the things you should really think about :)

Alternative to "Notification URL" to Handle Long Running API Process in Node

I am building an API that will take a long time to return data, up to 60 seconds while a conversion takes place. While running, I would like to keep the users informed of any errors and notify them which process in the conversion stage we are at.
This is pretty easy on the client since I can simply send a WebSocket event, but for a public API, that's not very practical.
I know I can request a notification URL and send updates to the given URL, but it seems cumbersome and potentially resource heavy. Is there another more efficient means to send progress notifications?
Ideally, the user consuming the api would be able to setup.
.on("error", function(err) {
//handle error
});
or something to that effect.
You're not really clear on who the consumers of your API are, what kinds of clients they're using, or what the workflow will look like. So there's a lot of different answers depending on what you're looking for and what resources you have available.
A non-exhaustive list:
REST endpoint polling
Understood that you aren't a fan, but this remains one of the best ways to do it for a wide range of clients, is one of only two (that I know of) ways to do it for purely browser-based clients. Performance wise, it's not awful if you setup your caching strategy appropriately and set throttle limits on your clients (which you should be doing anyway). I disagree that it's a PITA for clients to use consume, but that's opinion and you obviously feel differently. A way to mitigate that PITA is to offer an SDK that handles that mechanism for consumers.
Web Sockets
I get that you might be dealing with clients who aren't starting off in the web, but if a client can make a RESTful request, you could set the server to do the web socket upgrade if the client advertises interest in establishing same. I'm not a fan of this option as it feels more complex to me (more moving parts), but it's an option if you like web sockets and all/most of your clients will be web socket capable. Or you could just have the REST response be the URL to the web socket you're opening for that client.
Web Hooks
If your clients are likely to be other machines (esp. servers), then a web hook is a very good approach, especially if the event you want to raise can happen more than once and at unpredictable intervals. In this scheme, the client makes a REST request to you, part of the data they send you includes a URL that you will POST data to (in a format you specify in your API) when the event occurs. Obviously, they either have to leave that URL open to your POST or else you can agree upon some kind of credentialing that your server will respect.
TCP Socket
Similar to the Web Socket option, in that you'd probably have a REST request hit your endpoint, and then respond with the socket connection information/URI to a custom TCP socket. This is a bit nonstandard, but can be very useful and efficient in the right use cases. I haven't used it in a while so they may have changed it, but this is how Heroku's API used to handle streaming logs.
Pub/Sub or Message Queue or similar
Redis can do this, as can many others. In this scenario you're making a more generic solution where there might be more than one event channel clients can subscribe to, and so on. I dislike exposing Redis directly for security reasons, which means you'll still need to figure out how to handle the comms between Redis and the client (see above), but using it under the hood will at least buy you some of the conceptual logic of handling publishers and subscribers and so on; useful if you have more than one event as I said. This is a more heavyweight solution than the above, though, and will increase your sysadmin overhead by some amount (depending on your high availability needs, etc)

What's the best way to retrieve messages from the server for a chat application

I'm writing a chat application from scratch, and I'm trying to figure out the best way to retrieve messages from the server in real time. I've done a fair amount of research, and have come up with this: I could use web sockets, and I've seen it done before successfully. I could use long polling, but I'm wondering if that places greater stress on the server, or maybe is just not right for a chat application. I could poll the server every second, but that just seems like a waste of bandwidth. Suggestions? Thank you!
The websocket protocol is ideal for something like a chat application for several reasons.
As you've already identified, continous polling of the server is quite a waste of resources.
Using traditional HTTP requires the use of bulky headers which waste valuable bandwidth. Websockets allow for lean messaging.
Most importantly for your application, unlike HTTP, websockets are bi-directional, meaning that your server can independently send messages to your chat client. With HTTP, all communication must be initiated by the client, and you are restricted to a request-response type of communication. With websockets, if your client receives a message from another user on your chat service, the server can immediately and independently relay that information to the intended recipient.
So to answer your question. You should definitely go with web sockets. Since you lack traditional headers, you will have to do a bit of work when it comes to formatting the messages sent over the connection, but the efficiency is well worth the minimal effort it takes to set up your messaging model.
What? Do you need to and from a database on a dedicated server?
I would recommend Ajax with JavaScript or jQuery but i like to do my own coding so JavaScript.
If your showing data back and forth match i would probably use MySQL.
For example to query up the last known query if matches current then would not be updated.
If doesn't match loop up from last to rent match would be DESC if in Order by type. Anyways...
Hope this helps you decide on what you should use.
Although this is what is common on games, blogs, forums, chats with MySQL/SQL.

AJAX and Client-Server Architecture with JavaScript

I have to program websites, but I rather don't like the static HTML nature. I prefer more of a client-server architecture.
Now I've figured, that with XMLhttp, you can basically dynamically update your page and send/request for information/action to/from a server. So this would basically cover the client area.
But to complete a client-server architecture, it is necessary for the server to send/request information, too, without being queried.
Is there any way, for example for a chat server, to send back a received message to all clients (the clients use a web browser) without that the clients have to query in a fixed interval? I want to implement that one can see while you type something in.
There are several different ways to accomplish this. Some of them are already answered here, but I wanted to include a few more as well as my thoughts on them.
1. Polling
Frequent requests are made to the server to check for new info. This is the worst way to do this, but probably the easiest. If your site will have a low number of users, it might be worth doing it this way.
This can be accomplished by using setInterval(myFunction, n) in javascript to send XMLHttpRequests to the server every n milliseconds. Then, on the server, you respond to this with your new info, when you have it, or some message that implies no new info.
2. Long Polling
When the page is loaded, it makes a request to the server for new info. The server holds the connection open until there is something to send back. This method reduces the amount of network traffic used, but increases the resources used on the server. You can use this for a small number of users, but it doesn't scale very well.
The easiest way to do this is to have the page that handles the AJAX request simply wait for new information to be available, then respond. This can tie up a lot connections on your server. So, use with care.
3. COMET
COMET is basically long polling, but the server is setup properly for it. It knows that these connections aren't "real" and it uses less resources to handle them. This is a great solution for this problem, but it requires that the server is explicitly setup for this purpose. There are COMET servers and COMET addins for other popular servers, but it will require some setup and sometimes some money.
Implementing this on .NET isn't the easiest thing in the world. You can pay for solutions, try to find someone else's code that does something similar, or try to write it yourself. I've not found any decent free solutions for this. If someone else has, please comment.
4. RIA
Another solution would be to include Flash, Silverlight, or Java Applet on your page. People often do this by using a 1x1 object so that they can use Flash or Silverlight to talk to the server. If you don't mind adding the dependency, this is a decent solution. If you already know Silverlight or Flash, it could be relatively simple to implement.
You can find tutorials on the internet for each of these options.
5. Web Sockets
If you are on the cutting edge, you can look into Web Sockets. It's only available in the latest builds of modern browsers. It was part of HTML5, but it might be its own spec now. Regardless, it means that older browsers won't be able to handle it. But, if you don't mind limiting yourself to the latest of browsers, you can use this amazing feature.
I believe that Chromium is the only browser that currently supports it. However, there is work being done to implement this in Firefox and WebKit.
I'll spare you the controversy and simply say that this does exactly what you want it to. The Abstract of the spec says it all.
This specification defines an API that enables Web pages to use the Web Sockets protocol for two-way communication with a remote host.
Special Mention
If you are interested in the world of Node JS, you can't go wrong with Socket IO. It will implement the best of whichever technology is available to the browser.
Conclusion
The best option is Socket.IO on Node JS. However, for an ASP.Net solution, go for COMET or Web Sockets, if you can. Otherwise, using Flash/Silverlight isn't terrible. Finally, polling and long polling should be last resorts. You could always support one of these, then fall back to another if there isn't support for it in the client's browser.
Yes, you can use COMET.
The client has to tell the server when the client-user begins typing. You've got a couple options here.
Frequent requests from the server for the latest activity. This would be taking place for each user involved in the chat. The same request could be used to send user-specific activity to the server as well: "Jonathan is typing..."
Long-polling. This essentially requests information from the server, and the server keeps the connection opened until it has something to send back. So your requests are minimized, but your connections stay opened longer.
Depending on your traffic, type of data being transmitted, server-environment, and many other factors, one of these options may shine more than the other.
You can use Silverlight for push notifications. Look at PollingDuplexHttpBinding. Since you are using ASP.Net MVC, adding Silverlight will be easy.
Look at this page for more information.
Based upon the REST architecture the html system is based upon, the servers role is to simply act as a resource for the client to pull from. I am generalizing but there are tools to implement this type of action on the client side, rather than on the server side.
You are better off writing/using a library that can request updates from the server periodically. You can encapsulate these types of requests in a javascript object that can fire events. This way your client side script can act like it's getting notified from the server. Review some common stuff with COMET you can probably find some tools to help you client side code.
HTML 5 has some tentative attempts at this type of functionality, but if you want your app to work on older browsers, your better off using more stable methods, like AJAX requested updates.

Categories

Resources