-
-
Notifications
You must be signed in to change notification settings - Fork 4.4k
use SockJS instead of pure WebSockets #2321
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
This was meant to be just an experiment to see what would be involved in switching over to SockJS, and it turns out it was super easy. After dropping in the JS and tornado code, it was only about an hour of fiddling to make the changes necessary for it to be basically functional. |
I tried my own attack for unauthorized execution, and it seemed to be behaving exactly as expected (websocket connection closes with wrong cookie password), so no change seems necessary there. I tested, and can confirm that execution works in IE9 (CSS is obviously wonky), as well as behind an Apache reverse proxy. |
@minrk, do you want this one merge or was is just for experimenting ? |
I think we should do this, but it is certainly open to discussion, as it is a significant change. |
Is IPython going to stop supporting websocket when this is merged? I know it sounds selfish, but let me say that I really hope you don't merge this if that is the case, because my Emacs client will not work. |
@tkf - SockJS still uses websockets when they are available, but your client will definitely need to be updated since there is an extra handshake, etc. |
@tkf - in fact, it looks to be just a trivial URL change. |
Thanks for the link. I should have read the page more carefully. So I guess all I need to do is to connect to something like
instead of
|
BTW, in the page you mentioned it says:
Is this limitation fine for IPython? It needs two websocket connections (shell and iopub), right? |
I saw that, but I don't fully understand it, as everything appears to work fine. It may warrant further investigation, as that limitation probably only comes up when websockets are unavailable (even though I have tested this as well, and it still works everywhere I have tried). |
Added merged subclass, so that it can be used with only one SockJS connection (separate websocket connections still work the same). |
So how was this working before when you tested it? On Tue, Sep 4, 2012 at 4:22 PM, The Travis Bot [email protected]:
Brian E. Granger |
Before, it worked no differently to current master, just with SockJS handling fallback if websockets were unavailable. Now a single web socket connection will handle everything instead of two. I was able to artificially induce the failing case pointed out by @tkf with some custom config in Firefox (it does not seem possible with default config in FF or Chrome). |
I haven't had a chance to look at the code. Does this always use 1 On Tue, Sep 4, 2012 at 11:33 PM, Min RK [email protected] wrote:
Brian E. Granger |
Kernel.js only uses one websocket connection. It's pretty trivial to switch on a key in the message, so I don't think there is any real difficulty extending multiple channels on a single connection. That said, I wouldn't do this if SockJS didn't require it, so if we stick to requiring pure websockets, a 1:1 channel system is cleaner. The clear advantage of this: it works behind proxies, etc. in the many environments where websockets don't. It's simply a matter of whether we want to wait for systems to support websockets or not, and how long we expect that to take. Making the move to sockjs is extremely easy, so we can do it at any later point if we want to give up on waiting, etc. I didn't set out to make a PR, but just reading about how it might work resulted in fully working code, so I thought it might be worth it. |
On Wed, Sep 5, 2012 at 4:01 PM, Min RK [email protected] wrote:
|
I am not as worried about older browsers, but the proxy issue is huge. On Wed, Sep 5, 2012 at 7:17 PM, Fernando Perez [email protected]:
Brian E. Granger |
One more thing I can change: For backwards compatibility, the individual IOPub / Shell channels still exist, and are usable as pure websockets (not tested, but should be true according to sockjs spec). However, they, too, are SockJS, so the raw websocket URLs will be |
I don't view the URL scheme of web service of the notebook as being On Fri, Sep 7, 2012 at 11:16 AM, Min RK [email protected] wrote:
Brian E. Granger |
Hi, I'm interested in trying this, but am still a git noob. How do I merge this onto a ipython and what version? Thank you for this work. We need it badly to keep ipython alive for us! |
Hi @Sesshomurai , Which version are you currently using ? What you can do is try directly the state of this branch, that for example you can download it as a zip file autogenerated by github. I got the link by going to min's profile https://github.com/minrk/ipython go to If you want to do it with git, add a remote
fetch it
now you can try to merge
But please be sure to understand what you do, or ask for clarification. You could also get a look at https://gist.github.com/3342247
don't hesitate to ask if you need help, and also https://help.github.com/ is a good place to start learning git. |
Thanks so much for the response. I don't need to merge if its not necessary, I just want a complete ipython with this capability embedded. So I will try the autogenerated zip and see. |
I also didn't understand this part "...then sockjs then zip link in the headers...." Do I need to layer in other code from elsewhere? |
Longer version would have been: Go to the 'branch' tab. Select the 'sockjs' branch, now the 'zip' button in Does it make more sens?
|
I haven't noticed this issue before. Just FYI, we use SockJS in the Sage Cell server to communicate with an IPython kernel. I haven't had time to look at this implementation, but just in case it's useful, here are quick links to our code: javascript: https://github.com/sagemath/sagecell/blob/master/static/compute_server.js#L85 https://github.com/sagemath/sagecell/blob/master/static/compute_server.js#L989 server: |
this does not merge cleanly anymore... As this is pretty big, I would suggest cleaning it up and merging as it only improve things. |
rebased. One issue that we may want to address, alluded to by @jasongrout, is the restriction that SockJS requires only one active connection per client. This will limit the ability to connect to multiple kernels from one webpage. The restriction only actually applies when the websocket transport is unavailable. |
@minrk do you know if SockJS allows regular expression matching is the On Mon, Jan 14, 2013 at 4:00 PM, Min RK [email protected] wrote:
Brian E. Granger |
@ellisonbg I'm not sure what you mean. regex matching is already being used in the SockJS URLs. |
I looked at the code and I see that there is not native regular expression On Mon, Jan 14, 2013 at 7:19 PM, Min RK [email protected] wrote:
Brian E. Granger |
Ah, I hadn't remembered doing that. |
for IPython.external imports
Now only one SockJS connection is needed in the browser for both channels. The previous single-channel connections remain available.
SockJS seems to ignore empty messages
to hash ed3ce990a71e9dea5f82c153429b051186062431
in sockjs-tornado tornado >= 2.5 makes a minor change in the IOLoop API, so tornado.ioloop.PeriodicCallback >= 2.5 will not work with IOLoop from pyzmq < 3.2.
rebased |
I'm going to see if I can integrate the Sage MultiSockJS code, so that this will work with multiple kernels on a single page. I don't like how it changes the wire format from |
I really don't like the idea of taking things that belong in kernel related URLs (kernel_id, username, etc) and putting them into the message format. It breaks the main abstraction of the web, which is that resources are addressable using URLs. Some problems with this:
This also relates to the inability to do native URL regular expression in SockJS - you have to make the full WebSocket connection and then do your own URL parsing. I really want to like SockJS, but I am not excited about the changes it forces us to make. But maybe we should IRC about this, as it is pretty important. |
Based on IRC discussion, I won't do the MultiSockJS work. As proxy support for WebSockets improves (HA Proxy and node-http-proxy so far, nginx sort of / soon), the case for SockJS diminishes. I will leave this here for now, but at current pace, I expect WebSocket support to improve quickly enough that we won't need to make the compromises that SockJS would force upon us. This was just an experiment to see how easy integrating SockJS would be, anyhow. |
Just curious: is the IRC discussion archived anywhere? I too see SockJS as a temporary solution (in fact, the premise behind SockJS is that it is a temporary solution until websocket support matures). But it is an important hole for us to fill, as we are supporting legacy clients. |
We are less worried about legacy clients - by now all browsers have very good WebSocket support. You could argue that some people still use older browsers, but it is safe to say that those users are not our target market. The main area where we have run into problems with WebSockets is in the proxy support. But this is improved quicklyi and there are already some really good solutions. The only issue right now is that it forces people to choose a supported proxy, rather than letting them choose their own. |
On our end, we should record how many times sockjs uses a websocket connection vs. some other method. |
The gist of the IRC discussion was: drawbacks of SockJS:
drawbacks of WebSockets:
The drawbacks of SockJS aren't going to change, and the drawbacks of WebSockets are only getting smaller. The decision to go with SockJS is really one of: do we need to work in a proxy environment before the necessary proxy environment adds support for WebSockets. Six months ago, I thought the answer was probably yes. Now, I think it's probably no. |
Should we close this and open an issue to track the it. That will allow us to keep our open PRs on work that is actively moving foward. |
Sure. Closing here and opening as #2822 |
Should work in more environments than plain websockets.
Still some work to do, checking out authentication, etc., but the basics definitely work.
Third-party code added: sockjs-tornado (in IPython.external), sockjs-client (in static/sockjs).