taoensso / sente

Realtime web comms library for Clojure/Script
https://www.taoensso.com/sente
Eclipse Public License 1.0
1.74k stars 196 forks source link

Add support for other Clojure-side web servers (i.e. besides http-kit) #2

Closed ptaoussanis closed 9 years ago

ptaoussanis commented 10 years ago

This shouldn't be too hard (there's only a small surface area that actually interacts with http-kit) but will require potential servers to expose a sensible API that we can use.

Don't have a lot of time to look into this myself atm, so assistance would be welcome:

Otherwise any other thoughts/suggestions very welcome! Feel free to ping me with any questions :-)

gtrak commented 10 years ago

The Jetty's would be a quick-hit I think:

Could do something similar to the clojure.tools.logging selection: https://github.com/clojure/tools.logging/blob/master/src/main/clojure/clojure/tools/logging/impl.clj

Maybe dynamically loading the relevant namespace if they're present, added as provided deps: https://github.com/ToBeReplaced/jetty9-websockets-async https://github.com/lynaghk/jetty7-websockets-async

It also wouldn't be unreasonable to require the user to select an impl when they start up sente, just the resolution has to be dynamic.

I'm working with jetty now, but I haven't tried sente yet because of this issue (Jetty's not really a req for me, just haven't bothered with http-kit).

ptaoussanis commented 10 years ago

Hi Gary,

I'm interested in adding support for other servers, but I'll be honest in saying it's not a major priority atm. Am in the middle of a couple product launches atm, so time's pretty limited and I've got a lot of other big improvements I'd still like to make.

First step in supporting other servers would be to define a protocol that servers could implement. I'm not familiar with the async + WebSocket capabilities of things like Jetty, so would need to do a little digging first to find out what kind of interface they'd be capable of implementing.

Would also need to test that Jetty & co. are actually capable of handling the high-concurrency workloads necessary for something like Sente. Http-kit's exceptionally efficient at workloads like this.

So yeah, it's definitely on the cards - just realistically not something I'm going to have real time to investigate myself seriously soon.

ptaoussanis commented 10 years ago

Have removed the "pull-requests welcome!" label until I've handled my end in abstracting the http server interface.

malchmih commented 10 years ago

Here's another candidate, I believe: https://github.com/mpenet/jet

kul commented 9 years ago

Undertow support would be nice. Specially with the ring adapter and websocket support in place. http://undertow.io/documentation/core/websockets.html https://github.com/piranha/ring-undertow-adapter

tobias commented 9 years ago

I've done some work on creating a Channel abstraction for Sente, and using that abstraction to support both http-kit and Immutant 2. I realize you removed the 'pull-requests-welcome!' tag, but I'm hoping we can have a discussion about my implementation, and see what it would take to get it (or something similar merged in).

The full PR is https://github.com/ptaoussanis/sente/pull/101.

The real changes are in interfaces.cljx and both namespaces in sente/server/. The changes to sente.cljx to use the Channel procotol are extensive, but should result in no behavioral changes (as far as I can tell from playing with the example app). I tested with http-kit, Immutant embedded (which uses undertow directly), and deploying an Immutant war to the WildFly application server (which uses servlets inside undertow).

The differences between the new Sente Channel protocol and http-kit's Channel protocol are:

The as-channel function isn't part of a protocol, since there are no objects that directly represent a running server (starting an http-kit server returns a stop function, starting an Immutant server returns a map). Instead, as-channel is a regular function with a default implementation that throws. Implementations (currently in servers/http_kit.clj and servers/immutant.clj) alter the var root of as-channel (via provide-as-channel!) with a function that does the correct thing for that particular server. sente.cljx requires both of these namespaces, but they are guarded by the with-import macro to only code that will work based on which server is currently on the classpath.

Other changes include:

I haven't looked at what it would take to support any other servers (Jetty, etc), but hopefully the protocol is general enough to be adapted to them.

This is a first cut at solving this problem, I'm happy do discuss it and make any changes necessary to have this be part of the next Sente release. I updated the docstrings in sente.cljx to reflect these changes, but haven't yet made any changes to the README.

And if you would prefer to have channel abstraction and the Immutant implementation as separate PR's, I can do that as well.

tobias commented 9 years ago

I forgot to mention that this depends on an Immutant API that isn't yet in an official release, only incremental builds, so it may change some before a release. If the API does change, it should only affect servers/immutant.clj.

ptaoussanis commented 9 years ago

Closing here since we can continue any Immutant discussion at #101 and I've since added #102 for any other servers.

Busy working on a merge for #101.