Communication between Autobahn and Flask/Twisted - autobahn

I'm building a fairly simple application with Autobahn for WebSocket functionality. It's very similar to a chat server, but one thing I need to do is understand how to accomplish is how to essentially share resources between the WebSocketServerFactory object and my Flask application. The example here:
https://github.com/tavendo/AutobahnPython/tree/master/examples/twisted/websocket/echo_wsgi
shows how to combine both Flask and Autobahn, but in my particular use case, I want to be able to dynamically add a chat room when triggered by an authorized call from the Flask component. Is there any sort of best practice on how to go about communicating between the two components in Autobahn?

Flask is based on WSGI, which is a fundamentally blocking API. This doesn't blend well with Twisted or asyncio (the 2 asynchronous network frameworks supported by AutobahnPython).
Here are 2 options:
using Twisted callFromThread to communicate from a background thread running WSGI to the main thread running Autobahn
Twisted Klein http://tavendo.com/blog/post/going-asynchronous-from-flask-to-twisted-klein/

Related

Integrating Zope with socket-io

Is there a way of integrating Zope 2 (2.13.19) using Python 2.6.8 with socket-io ?
I've found https://python-socketio.readthedocs.io/en/latest/ but it doesn't seem to fit the requirement.
Zope contains a traditional HTTP server, but you could write a ZEO client that would use the socketio library and integrate with Zope's transactions.
It seems that at least the version which is using eventlets should be possible to implement under Python 2.7.
https://python-socketio.readthedocs.io/en/latest/intro.html#server-examples
What Plone version are you using?
I used a slightly different approach in the past, to realize this. I was using a small Pyramid app, which was implementing the socketio (similar to the WSGI way of this library) and was subscribing a Redis PubSub channel. Plone was using event handlers to send messages to the Redis channel which would then consumed by the Pyramid app and send to the socket.
This above library should work and the easy way to use it, would be the same way i did, as a WSGI app together with messaging.
Starting with the upcoming Plone 5.2 you can run Plone on WSGI even under Python 3. This might be a better fit, together with the WSGI app which provides the socket.io support.
The library supports also Redis for multi-server support.
Optional support for multiple servers, connected through a messaging queue such as Redis or RabbitMQ.
The integration with Zope transactions is doable, I had to do that for the Redis messages too.
in the community forum is an interesting thread on that topic too:
https://community.plone.org/t/plone-socketio-websockets/6453/14

Why do we need products like Pusher and Socket.io to establish a websocket connection?

I've been reading about websockets and SaaS like Pusher and Socket.io recently, while working on my Laravel chat practice application. What I don't understand is, why do we need external software to establish a websocket connection? Can't the server code like Laravel just directly establish the connection with the front-end like Vue.js? Why does it have to go through the middleman like Pusher and Socket.io? Sorry for the noob question.
It doesn't have to.
Those pieces of software just happen to make it trivial to work with the Websocket protocol.
Remember, Laravel is an opinionated framework. This means that it will pick and choose its own libraries to abstract away these kinds of concepts for you so that you don't have to worry so much about what's going on under the hood.
Basically, there are two components that you need in order to be able to work with Websockets:
A Websocket Server
A Websocket Client
The reason Laravel doesn't communicate directly with the front-end using Websockets is because Laravel itself isn't a Websocket server. At least, not really. And while PHP does have support for working with the Websocket protocol - and even some libraries to leverage it a little more nicely - it just isn't used to handle long-lived processes as often as other languages.
Instead, Laravel uses the Pub/Sub functionality that Redis provides to listen to events that occur through Redis and the Predis library. The reason why it does this is because Laravel is better-suited as a middle-man for the websocket server, and all connected clients.
In this way, Laravel can both pass information up through to the Websocket server using Broadcasting Events, as well as receive event information from the Websocket server and determine if users have the ability or authorization to receive them.
If you don't want to use Pusher, there is a library that will allow you to run your own Websocket Server specifically for Laravel called Laravel Echo Server.
Under the hood, this library still uses Socket.io and Redis in order for all moving parts to communicate with each other seamlessly in a Laravel web application. The benefit here is that you won't need to worry about the number of messages being sent by the server.
The downside is that you now have to know how to manage and maintain this process on your server so that the Websocket Server will know to turn on every time you restart your server, or if a failure happens, etc.
Check out PM2 to learn more about running and maintaining server daemons.
If you don't agree with Laravel's opinions on how to handle Websockets, then you could theoretically use any other server-side language to handle the websocket protocol. It will just require a greater working knowledge of the protocol itself; and if Laravel needs to work with it, you'll have to know how to write the appropriate Service and Provider classes to be able to handle it.
Short answer? You don't have to use them. Knock yourself out writing your own server and client side websocket implementation.
Longer answer.
Why use Laravel? I can do all that with straight up PHP.
Why use Vue? I can do all that with vanilla javascript.
We use libraries and frameworks because they abstract away the details of implementation and make it easier to build products. They handle edge cases you don't think of or things you don't even know that you don't know about because they are used by thousands or millions of developers and all the knowledge and bugs they have encountered and fixed are baked into the implementation.
This is one of the hallmarks of software engineering, code reuse. Don't repeat yourself and don't write any software you don't have to. It allows you to focus on building a solution for your particular requirements, and not focus on building a bunch of infrastructure before you can even build your solution.
I've never used Pusher, but it looks like, yes, it is a SaaS product. But Socket.io is open source.

web2py - do I need another server for a real time application?

In the web2py examples there is a websocket example which uses tornado here:
gluon/contrib/websocket_messaging.py and this requires another server to be started namely tornado. My questions is, do I need another server? Should I only have one server to handle both the websocket stuff and the normal http requests?
Also, it seems tornado is the server of choice for the 2nd server, could that be something different?
I'm a bit of a newbie to websockets (and webapp development) so any comments/links that would help me better understand this would be appreciated.
Python WSGI based frameworks such as web2py are typically served via threaded web servers. A typical HTTP request occupies one of the server threads only very briefly in order to receive the incoming request and deliver the response, then freeing the thread to serve another incoming request.
Websockets (and long polling), on the other hand, require a long-lived connection between the client (i.e., browser) and the web server. A websocket connection will therefore occupy a thread indefinitely, so you can only have as many connections as you have threads, thus limiting the application to a relatively small number of concurrent users.
In order to enable many simultaneous websocket connections, it is therefore best to serve websockets via a server that features non-blocking network I/O, such as Tornado. For more details, see http://www.tornadoweb.org/en/stable/guide/async.html.
Another option is to use Gevent with monkey patching, which can be used in the context of a WSGI application as described here. Keep in mind, though, that any libraries you use that involve network I/O (such as database drivers) must be compatible with this approach (either via monkey patching or code explicitly designed for coroutines).
If realtime/server-push functionality is a major aspect of your application, and especially if you are new to web development, you might instead consider a framework built for this specific use case, such as Meteor.

Scala web frameworks that don't use one thread per request

In the Clojure world, the main web framework Compojure turned out not to be good for heavyweight ajax and long-running polls because it used a thread per request. (Not blaming the brilliant guys who put it together, it solved the right problem at the time.) So they ended up building Pedestal.
I'm keen to avoid this same issue when selecting a Scala Web Framework.
So assuming I have an Ajax heavy web application with SSE and Websockets and other messaging going on. Assuming (as a hypothetical example) this is a multi-player poker application with chat and social notifications.
My question is - out of the major Scala Frameworks (Lift, Play 2, Scalatra, Pinky, Sweet), which ones don't use one thread per request?
Assumptions:
by this I mean do not block threads while listening for incoming requests

Real-time client-server interactivity using Websharper

I'm just learning Websharper but, in the short term, I have a business problem that I am trying to solve. I've written a server and WPF-based client that allows the user to vary inputs using controls like sliders and obtain feedback from the server in real-time (i.e. there is no "submit" button).
I'd like to convert this desktop GUI app into a web app using Websharper. How might I do the background request-response to the server triggered by the user sliding and slider and resulting in feedback visualized asynchronously in the web page?
I imagine the most obvious way is to simply make a bunch of [<Rpc>]-decorated methods for your server-side logic and then simply invoke them on any change in the UI. IIRC, Websharper handles the client-server transition transparently, i.e. if you call a server method, the necessary proxy will fire to get you the results.
As has been pointed out you may rely on RPC methods, but this might give unacceptable latency.
At IntelliFactory we are now working on a project that required asynchronous bi-directional and low-latency communication between the server and the client. We ended up using the WebSocket protocol. We are planning to document and release the code into a reusable library soon for people with similar requirements.
The prime advantage of the WebSocket protocol for our purpose was that it allowed to maintain state on the server side of the connection. Our server is a worker role running in Windows Azure. The server is selected randomly by the Azure load balancer when the WebSocket connection is established, and the client talks to the same server while the connection is open. This allows maintaining expensive to initialize per-connection state on the server.
The disadvantage of the WebSocket protocol is lack of support by older browsers. A portable low-latency alternative is SignalR that uses some form of HTTP polling to emulate the functionality on older browsers. Unfortunately we have so far failed to adapt SignalR to our requirements on Azure. It should theoretically be possible but since AFAIK SignalR follows a mostly stateless design this would require coding up a router to redirect messages and "undo" the effects of Azure load balancer.
I don't know integration points of WebSharper, but Rx has many nice concepts and functions for functional and reactive event processing like throttling (needs for slider and async network calls).
https://github.com/Reactive-Extensions/RxJS
https://github.com/panesofglass/FSharp.Reactive

Resources