Websockets - passing-off open connection to another server? - network-programming

Situation: Two web servers, and a browser client. The client has an open websockets connection with Server A. Server A decides that this client should really be serviced by Server B.
I would like to know if there is any established technique for performing this hand-over?
It would be great if this could happen as invisibly as possible for my client side code - but I haven't come across any feature which would allow this.
Best I have come up with so far is Server A sending a 'you should really deal with Server X' message, client closing the WS session and then sending some http request which will get routed to the correct server, and upgraded to WS. I can see the presense of load balancers making this complicatied though.
Any thoughts?

From a programming point of view, the socket connection is treated as an open file handle, and that's what you are trying to pass along. For that, I would check out the question "Portable way to pass file descriptor between different processes" for a handful of methods.
But if you are not writing your own web server, and are looking for an off-the-shelf method for Apache, etc, this probably won't help you much.

Related

iOS - mobile application is sending two this same request in milliseconds apart

In our application we observe multiple ( two ) these same requests send from mobile application to server in milliseconds apart.
As we discuss the problem with dev team, they said they don't send two requests from an application perspective, but on the server-side, we see exactly these same two requests.
Does anybody know if iOS has this type of functionality to keep resending this same request in case of a lost connection or any other case? ( This is milliseconds that server doesn't respond yet )
The application should send only one request, wait for response success/failure, and then resend as needed. So far as we know, there is no logic in the application itself that will trigger sending two requests from the app to the server in milliseconds apart.
Thank you for any suggestions.
It's hard to tell without looking at the code or knowing your network infrastructure.
What I'd suggest to do first is to run the app through a debugging proxy server like Charles, Proxyman or mitmproxy. If it shows multiple requests, most likely the app is to blame, I'd bet on a concurrency bug.
If the debugging proxy shows just one request but your server observes two, you'll have to check your network infrastructure, it might be that some load balancer or reverse proxy is configured incorrectly.

How to update a web page from requests made by another client (in rails)?

Here is my need:
I have to displays some information from a web page.
The web browser is actually on the same machine (localhost).
I want the data to be updated dynamically by the server initiative.
Since HTTP protocol is actually a request/response protocol, I know that to get this functionality, the connection between the server and the client (which is local here) should be kept open in some way (Websocket, Server-Sent Events, etc..)
Yes, "realtime" is really a fashion trend nowadays and there are many frameworks out there to do this (meteor, etc...)
And indeed, it seems that Rails supports this functionnality too in addition to using Websockets (Server-Sent Events in Rails 4 and ActionCable in Rails 5)
So achieving this functionnality would not be a big deal, I guess...
Nevertheless what I really want is to trigger an update of the webpage (displayed here locally) from a request made by another client..
This picture will explain that better :
At the beginning, the browser connects to the (local) server (green arrows).
I guess that a thread is executed where all the session data (instance variables) are stored.
In order to use some "realtime" mechanisms, the connection remains open and therefore the thread Y is not terminated. (I guess this is how it works)
A second user is connecting (blue arrows) to the server (could be or not be the same web page) and make some actions (eg. posting a form).
Here the response to that external client does not matter. Just an HTTP OK response is fine. But a confirmation web page could also be returned.
But in anyway the thread X (and/or the connection) has no particular reason to be kept.
Ok, here is my question (BTW thank you for reading me thus far).
How can I echo this new data on the local web browser ?
I see 2 differents ways to do this :
Path A: Before terminating, the thread X passes the data (its instance variables) to the thread Y which has its connection still open. Thus the server is able to update the web browser.
Path B: Before terminating the thread X sends a request (I mean a response since it is the server) directly to the web browser using a particular socket.
Which mechanisms should I use in either method to achieve this functionnality ?
For method A, how can I exchange data between threads ?
For method B, how can I use an already opened socket ?
But which of these two methods (or another one) is actually the best way to do that?
Again thank you for reading me thus far, and sorry for my bad english.
I hope I've been clear enough to expose my need.
You are overthinking this. There is no need to think of such low-level mechanisms as threads and sockets. Most (all?) pub-sub live-update tools (ActionCable, faye, etc.) operate in terms of "channels" and "events".
So, your flow will look like this:
Client A (web browser) makes a request to your server and subscribes to events from channel "client-a-events" (or something).
Client B (the other browser) makes a request to your server with instructions to post an event to channel "client-a-events".
Pub-sub library does its magic.
Client A gets an update and updates the UI accordingly.
Check out this intro guide: Action Cable Overview.

ruby on rails chat application over port 80 which is hosting site agnostic(no flash and websockets)

Wanted to build a chat like application(i.e bidirectional message passing to multiple connected clients). Looked at the Faye gem but it opens a new port apart from port 80.
The big problem is that if the client is behind firewall all access to other ports except 80 are restricted and not all the hosting sites provide the support.
The ActionController::Live component does not have any mechanism to register the clients so that the message can not be passed to the registered clients on a specific event occurance.
Looking for a solution where the alive clients are stored in a collection(array or somthing like that) and when any of the alive client sends a message then the collection can be iterated and the messages can be written on it. All of these must happen only through port 80.
Good question - having implemented something similar, let me explain how it works:
Connections
A "live" web application is not really "live" at all - it's just got a persistent request; meaning it still works exactly the same as a "normal" Rails app, except clients don't close the connection (hence why you're interested in opening another port)
The way you handle the request is where the magic happens. This is as much to do with the client-side, as it is with Rails (server-side)
Clients
When you connect to a "chat" application, your browser is opening a live connection with the server. This will typically be done with either server sent events (Ajax long polling), or web sockets
The way this works is to open the connection using the normal Rails ActionDispatch middleware, and then allow you to connect
If you've played with ActionController::Live functionality, you'll find that it's not a typical controller-action. It's actually a separate technology (like resque or Redis) which you call from another controller action. This gives room to do cool things with
Server
The way you'd handle something like this is to separate the "live" functionality and the "normal" Rails app. It's one of the current down-falls of Rails - in that it's probably better to implement something like nodeJS with socket.io to handle the live data (with an endpoint like chat.yourapp.com), whilst using Rails to handle authentication & authorization
From a server perspective, its job is to handle incoming & outgoing requests -- not to handle persistent connections. So I guess you may want to look at ways you could "outsource" the websocket connectivity. Admittedly, my experience is slightly thin in this area, so you may do well searching the net
Solutions
We've had a lot of success using a third-party system called Pusher
This is a web socket system which allows you to open a persistent connection as a client, and integrates with Rails in a similar way to Redis (you can push to it)
This means you can host the "chat" application with Rails (http://yourapp.com/chat), send the messages to your Rails app (http://yourapp.com/chat/send), and handle the incoming chats from pusher (or similar)
Maybe you want to use my open source comet web server (https://github.com/TorstenRobitzki/Sioux). There is a ruby web chat example. I use this to implement an interactive role playing map with rails (http://dungeonpilot.com).

Would it be better to post message data or send it through websockets?

I have an app running where a socket connection is constantly maintained (using socket.io). Data that needs to be sent is similar to that which you might see in a chat application. Would it be better to have it sent through POST (essentially, post that data, prevent page redirect, and then return the new page state with websockets), or just send it through websockets? What are the advantages to each?
(You might want to explain what you're trying to accomplish in more detail. Do you want to implement chat-like functionality).
A WebSocket gives you a TCP-like connection protocol over an HTTP connection. It's full duplex and lets you push and pull content in both directions. The connection is initiated from HTTP which "upgrades" the connection type. It gives you flexibility with some added complexity. I don't think it works across old HTTP 1.0 proxies.
A simple HTTP POST is more brute force. Unless you use ajax-ish techniques it pushes data to a web service and responds with a new web page to replace whatever's in your browser.

Invoke controller action from a web service

I have an ASP.NET MVC application presenting some data and I want it to
open a new tab, or
redirect to a new view
when a web service gives me a signal. This WS is supposed to handle some external data and requests and when some specific action is called, I want it to be able to give my web application some kind of signal.
I was thinking about using Html.Action to an asynch controller but then I don't know how to provide the signal from the WS to the controller (or all instances of them).
Hopefully, it is understandable. Do you have an idea what needs to be done?
Thanks in advance.
So basically your problem comes down to the fact that server state is changed (through WS) and we want to make something happen at the client side where the your web app is being viewed.
Frankly it's not straightforward. Internet works on the Client -> Server architecture. User sends a request to the server, server responds. What you are trying to do is reverse of it. You want to send a request from server to user. HTTP protocol doesn't work like that.
Right now, to do something similar following two strategies are used:
Websockets : try searching them on google. You create a socket between the client and server and once server gets updated by the WS, it sends a request to the client through the socket. You can ask it to navigate to a different view or open a new window. The downside with it is that its not supported by the majority of the browsers. Might take a year or so to be. Not really recommend now.
Polling : You can make Ajax requests from your browser to server in certain intervals (you know like every 5 seconds) and see if the server state has changed or now. If yes, then do your stuff. That's the most common technique. Twitter.com uses it. There is also another version of it called Comet or Long Polling but I won't confuse you with that.
The important thing to note here is that whatever you want to do (open tab, change view etc) you have to do it through Javascript at the client side.
hope that helps

Resources