Comments (3)
(pasting in email reply from kanaka)
I'm struggling with how to integrate websocket.py with an existing Python service. I'm hoping you can provide some advice. Here's the case:
We have an existing web service written in Python, based on Cheetah templates. The engine is the Python stock SocketServer and BaseHTTPServer. A separate binary/process deals with TLS encryption and communicates with the Python process over a UNIX socket. The service is created with:
class ForkingHTTPServer(SocketServer.ForkingMixIn, SocketServer.UnixStreamServer):
The handler derives from BaseHTTPRequestHandler. All in all, pretty standard and straight forward.
Now, the question is how websocket.py could be used in such context. I've noticed that websocket.py does not use any stock service engine, but rather creates sockets, forks etc manually. In order to provide websocket.WebSocketServer with existing file descriptors etc, we would need to override WebSocketServer.start_server(), but is this really safe and intended?
That's a really good question. There are several factors that complicate the situation:
- The first complication is that in order for websockify to reply to Flash policy request it needs to be the first consumer of the socket because the Flash policy request is not compatible with normal HTTP. This is less and less important over time as native support for WebSockets becomes more prevalent so eventually the Flash policy response will probably go away.
- Another complication is that in order to support the older Hixie protocol we need to be able to read 8 raw bytes after the request headers during the WebSocket GET handshake. This is one of the reasons why I override do_GET in the WSRequestHandler. At some point soon when I get the chance I will merge your pull to remove Hixie protocol so this will be less of an issue. The only remaining reason why I am defining WSRequestHandler is to parse headers and provide a simple embedded web server if enabled (--web).
- I want the default mode of websockify to not serve normal HTTP requests. Being able to serve web requests is just a convenience really. However, the built-in web serving functionality is pretty basic and doesn't perform well.
- websockify currently supports python 2.4 through 3.X in the same code base. The HTTP modules have changed subtly across those releases but I would still like to continue to support all of them if possible in the same code base (python 2.4 is still surprisingly prevalent and it's the thing that I get the most reports about if I break it).
Anyways, the biggest issue really is that websockify needs direct access to the raw socket after the handshake. This might be a lot easier to do if you drop Flash policy and Hixie. It's been a while since I looked into the structure of HTTP classes to see if there is an easy way to access the underlying socket. For example, I recall that rfile and wfile and streams over the socket and those are not sufficient. One possibility would be for the desired handler to be passed in as an argument and then monkey patched to do what is needed and capture the raw socket.
Certainly, if you came up with a patch to make websockify more cleanly integrate with existing python web serving classes, I would be happy to consider merging it into the upstream. In particular if there is a way to detect a Flash policy request (e.g. by catching an exception or something like that) then that would be ideal and allow Flash policy requests to be handled.
Another problem is that init prints stuff to standard out. Shouldn't it use msg() instead?
Yep! There are a couple other places that use print() to that should be changed also. Send me a patch :-)
In general, websocket.py is very nice, but I think it would be even better if there was a clear separation between the Websocket "protocol" and service stuff such as sockets, TLS, VNC recording etc. Thoughts?
In general, I strongly agree. I don't have time to work on this directly except to give advice, review patches, and merge in good changes. It's no longer part of my day job and I just started part-time school, so as much as I would like, I don't have much opportunity to improve websockify or noVNC. The main open source project that I work on when I do have a few moments of free time is clojurescript-in-clojurescript (https://github.com/kanaka/clojurescript [github.com]).
BTW, websockify has quite a bit of functionality so there is a fair amount of baggage to pull forward with major refactoring. However, the base functionality of websockify is actually quite simple: accept WebSocket connections, open a raw TCP socket, and then bridge between the two by framing/unframing to WebSocket. I am willing to host two python implementations for a while in the upstream repo and gradually add the current functionality to the new implementation as I (or others) have time. Just thought I would throw that out there to try and entice you ;-)
from websockify.
That's a really good question. There are several factors that complicate the situation:
- The first complication is that in order for websockify to reply to Flash policy request it needs to be the first consumer of the socket because the Flash policy request is not compatible with normal HTTP. This is less and less important over time as native support for WebSockets becomes more prevalent so eventually the Flash policy response will probably go away.
Yes, in our case, we do not need support for Flash policy request handling.
- Another complication is that in order to support the older Hixie protocol we need to be able to read 8 raw bytes after the request headers during the WebSocket GET handshake. This is one of the reasons why I override do_GET in the WSRequestHandler. At some point soon when I get the chance I will merge your pull to remove Hixie protocol so this will be less of an issue. The only remaining reason why I am defining WSRequestHandler is to parse headers and provide a simple embedded web server if enabled (--web).
I see. We do not need Hixie, but a basic web server.
- I want the default mode of websockify to not serve normal HTTP requests. Being able to serve web requests is just a convenience really. However, the built-in web serving functionality is pretty basic and doesn't perform well.
Ok.
- websockify currently supports python 2.4 through 3.X in the same code base. The HTTP modules have changed subtly across those releases but I would still like to continue to support all of them if possible in the same code base (python 2.4 is still surprisingly prevalent and it's the thing that I get the most reports about if I break it).
Yes, our requirements are "Python 2.4 or newer 2.X version", ie we do not support Python 3 yet.
Anyways, the biggest issue really is that websockify needs direct access to the raw socket after the handshake. This might be a lot easier to do if you drop Flash policy and Hixie. It's been a while since I looked into the structure of HTTP classes to see if there is an easy way to access the underlying socket. For example, I recall that rfile and wfile and streams over the socket and those are not sufficient. One possibility would be for the desired handler to be passed in as an argument and then monkey patched to do what is needed and capture the raw socket.
The documentation for the SocketServer module says: "For stream services, self.request is a socket object". Limiting ourselves to stream services should be a reasonable limitation. However, one problem is that BaseHTTPRequestServer et al assumes that rfile is available, since it wants to use .readline() etc. Another problem is that rfile is buffered by default, so if we switch to using the raw socket later in, we might have stale data in the rfile buffer.
In general, websocket.py is very nice, but I think it would be even better if there was a clear separation between the Websocket "protocol" and service stuff such as sockets, TLS, VNC recording etc. Thoughts?
In general, I strongly agree. I don't have time to work on this directly except to give advice, review patches, and merge in good changes. It's no longer part of my day job and I just started part-time school, so as much as I would like, I don't have much opportunity to improve websockify or noVNC. The main open source project that I work on when I do have a few moments of free time is clojurescript-in-clojurescript (https://github.com/kanaka/clojurescript [github.com]).
BTW, websockify has quite a bit of functionality so there is a fair amount of baggage to pull forward with major refactoring. However, the base functionality of websockify is actually quite simple: accept WebSocket connections, open a raw TCP socket, and then bridge between the two by framing/unframing to WebSocket. I am willing to host two python implementations for a while in the upstream repo and gradually add the current functionality to the new implementation as I (or others) have time. Just thought I would throw that out there to try and entice you ;-)
:-) I'll see what I can come up with.
from websockify.
is there an example script showing how to use this? I for example, am using Flask. Based on what I gleaned last year from this repo and maybe others, I came up with a solution that is working albeit slowly, using two threads once a wss
connection comes into Flask. Then I just open a socket, and thread1 listens (recv
) on it and sends to the ws
, thread2 listens on the ws
and forwards to the socket. Performance is low single-digit frames per second. Now that I've proven the concept works, I'm looking to clean things up.
from websockify.
Related Issues (20)
- systemd script to startup
- about target-config HOT 1
- tests failed on macos
- Logging and monitor HOT 1
- How to Revoking a Certificate of VNCServer? HOT 1
- TypeError: 'str' object cannot be interpreted as an integer
- noVNC & websockify in Docker Compose on Raspberry Pi 4 using RealVNC Server HOT 1
- Installation fails HOT 1
- wss: via ssl on linux debian board HOT 1
- Readme is missing examples HOT 1
- Failed when connecting: Connection closed (code: 1005) HOT 2
- soft reload possibility HOT 1
- novnc session getting disconnected after 30 min if left idle HOT 5
- Server disconnected (code: 1015). Open developer tools (F12/Ctrl+Shift+I on Windows, Option+Command+I on Mac OS) and switch to "Console" for details HOT 1
- Exception when use JSONTokenApi as token plugin
- how to connect to tls vnc server HOT 4
- Extra parameters HOT 2
- Connection pooling HOT 1
- which option disabling directory listings HOT 1
- Websockify: Integrate xterm.js HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from websockify.