Is it enough to cleanup on disconnect? What happens if a browser disappears before sending an explicit disconnect?
What is the recommended pattern for server side cleanup, so that the resources bound to the connection are not leaked (e.g. Namespace)?
(using gevent-socketio, if it matters)
If you use WebSockets as transport, it would automaticaly disconnect the socket on browser close.
If you use xhr-polling for example it would not automaticaly disconnect (speaking about gevent-socketio).
My approach when xhr-polling is used was:
Saving the socket session id among with logged in user id in database
On next user login detect if such a record exists
Use the stored session id in the record to disconect the unused socket since the fresh user login would generate new socket
This is not rapid solution since you may have unused sockets connected until new login is performed by the user, but it performs a kind of cleanup when the user log in.
This article may be a hint to something more creative than mine solution: http://flask.pocoo.org/snippets/71/
Related
Heads up: flask-socketio sessions are not User Sessions mentioned below.
I'm restructuring my React app to handle multiple User Sessions defined by a string in the URL. Whenever a browser tab/window connects to the server with the User Session in its URL, I will record it as a connection of that User Session, and multiple connections of the same User Session will be stored in a list.
I found request.sid might be the right thing to identify these connections I mentioned, and I can add the value of request.sid to the list whenever a new connection from a browser tab/window is built. Each tab/window is assigned a different such sid, i.e. socketio session id, and multiple socketio session ids belong to a single User Session of my definition.
However, I don't know when a browser connection is lost due to internet disconnection. Usually, it's handled by heartbeat mechanism, and flask-socketio already has a heartbeat built in, so I'm wondering whether I can catch an event when the built-in heartbeat finally exceeds the expiration time, so that I can go ahead and delete the sid from the connection list.
Any ideas/suggestions for me? Thank you in advance!
You can listen to the disconnect event:
#socketio.on('disconnect')
def client_disconnected():
# remove request.sid from your application state
What can be the reasons that cause a socket.io session to be crashed and server returns invalid session or session is disconnected ?
There is a specific situation that causes these problems with the session. When a client fails to send the pings at the expected interval the server declares the client gone and deletes the session. If a client that falls into this situation later tries to send a ping or another request using the now invalidated session id it will receive one of these errors.
Another possible problem with the same outcome is when the client does send the pings at the correct intervals, but the server is blocked or too busy to process these pings in time.
So to summarize, if you think your clients are well behaved, I would look at potential blocking tasks in your server.
Ok, I'll illustrate my problem in this figure project's architecture .
In fact, I have a websocket between the react app and the rasa ( tool for creating chatbots) based on flask. bot response need to access to an external API to retrieve some data. Here where things go wrong. Sometimes, these requests take too long to return a response, and that's when websocket misbehave.
I'm new to software development in general, and I'm writing a backend for a simple ride-sharing iOS application (which I'll develop later). I'm using Vapor to create the backend.
When a user makes a trip request to the API, I want to create a new trip and establish a websocket session between the user and a driver. The problem I'm having is how can I notify a driver that a request is in and add him to the session?
Here's what I've come up with so far, although I'm not sure if it's going to work:
When a trip request comes in, I would create a session and a trip object with the session id. When a driver visits the "Trip requests" tab in the app he would make a get request to retrieve active trip requests. When he then clicks on one of the trip requests, he would make a request with the session id of that particular trip to be added to that session.
The problems I'm seeing with the above solution is that that would make the User the Poster, and the Driver the Observer, which I'm not sure is the way to go since I want the driver to act as a poster (to send location updates so that the user can track the driver on the map in real time).
Another problem is that users would have to wait indefinitely before a driver accepts their request.
Is there a better way to notify the driver of a trip request? How can I go about achieving this?
First, you will get trouble when trying to establish a direct connection between user and driver, because it's quite difficult to directly connect to an app on a smartphone (changing IPs, NAT, firewalls and opening ports are some of the problems).
I'd suggest, you implement some kind of REST API for the trips/trip requests. To notify the driver or send updates back to the user, you can either use push notifications (for iOS it's APNS) or websockets. In the best case both for different situations.
Here are some hints for further research on those topics:
WebSockets: In Vapor, an example chat app using websockets , WebSocket wrapper for Vapor
Push notifications: Gorush, push notification server, Apple Notifications, (WIP: APNS on NIO)
I hope that helps for your next steps. Your question is quite broad to be more specific.
I'm writing a web client that needs to deal with lost connection.
If you are connected to a server using HTTPS and Internet connection drops, will the server lose the session information?
Once Internet connection is restored, does the client need to re-login to the server or does it depend on the server?
Usually the server determines how long a session lives (by defining a session timeout) and how a session (if at all) is persisted between single requests. The server sends a cookie with the session information (a session key) back to the client, so when the client sends the next request including the session cookie, the server knows which session to use.
Having said is - there is no information between two requests, whether the internet connection was lost in the meantime. As long as the server still has the session and the client still has the corresponding cookie, everything should work as expected.
On the other hand, even if there was no interrupt in the connection at all and both server and client were up and running, but without talking to each other (i.e. without requests), the session might be lost because of a simple timeout on the server side.
So on the server you might receive requests for resources that are secured or need a certain session state - and there is no such session. And on the client side you always might receive responses that indicate that a login is necessary.
Both cases must be implemented properly.
The HTTP protocol itself is stateless i.e. each request is served as is without any relation to previous of future requests.
To overcome this you can use client Cookies. Your cookie can keep a session state identifier which can be sent back to the server after a connection drop to resume the previous state.
In addition to that you can build a session management module which handles session persistence.
first it depends on the type of session you are talking:
ssl session
This can cause an shortend renegotiation. If the Server support it.
That mean it save CPU time.
http sessions
here it does not only depend on the server but also on your web page code.
For example if the session drop's while delivering the page conntent.
The servlet receive an connection reset during flush and may invalidate the session.
Also id depends if the session is bound to the ip adress. Than it depends if the
new connection use the same ip adress.
There is no simple answer as you maybe expected. Since it depends on to many points.
As the others already stated you can "persist" a connection by using a SessionID, which is recommended to be stored in a cookie. Most of the modern Environments like PHP and ASP.NET use this mechanism which can deal with lost connections.
Please refer to https://www.owasp.org/index.php/Session_Management_Cheat_Sheet for security considerations for implementing a secure Session Management.
Additionally what you can do with SSL is to build the Session Management using client certificates. The user is identified by the unique certificate which is issued to him. This has the advantages that the client does not have to login first. On the other hand you have to issue a client cert to every client, which might be complex.
Use cookies to store the session information, once connection is lost you can easily get the information from the cookies. call the cookies using condition i.e. if session lost call for the cookie. use Php to store information in the session and call the cookie
Is there a way to open a websocket on one page and then reuse it on another page (within the same tab, after a user clicks on a link, for example) rather than have to open a new websocket after each page load? Is browser storage able to hold onto an open socket?
The aim is to be able to keep to one websocket per user (or tab) and it would be great to do this without needing to move between pages in a non-traditional way, for example loading content into a div using Javascrpt each time the user interacts with the page.
The answer is no.
Even if the socket is not explicitly closed by calling mySocket.close();, the socket will be closed by the browser on reload.
I tried storing the Web Socket object in local storage and using it to retrieve data again. The object returned is valid, but the connection in not there anymore. Because, when the page reloads, the socket is ungracefully terminated.
Message at server side says:
[Errno 10053] An established connection was aborted by the software in your host machine
There you go...
A different approach would be to keep the user instead of the socket across different pages. By that i mean you store the client's ID in a cookie with javascript, each time the user try to open a new socket from any of your website pages, you send this ID to the server and then the server have a way to know that this new connection is from the same user.
I've done that in a recent project and it work perfectly :) Depending on what you are planning to do, you can keep the state of the user on your server with his ID, or store it in an other cookie, or event use flash to store it in a shared object !
Shared Web Workers would allow you to share a WebSocket connections for multiple tabs that are loaded from the same origin/site.
Shared Web Workers are only currently supported on Chrome, Safari, Opera.