cgmartin / clj-wamp

WebSocket Application Messaging Protocol (WAMP) for Clojure and HTTP Kit
http://cljwamp.us
Eclipse Public License 1.0
54 stars 12 forks source link

WAMP Node Version 2 #14

Open sundbry opened 9 years ago

sundbry commented 9 years ago

This pull request includes functionality for a WAMP Version 2 node implementing "callee" and "publisher" roles. Tested with a crossbar.io router.

cgmartin commented 9 years ago

@sundbry Wow, this looks great! Any interest in taking ownership of this project and repo?

sundbry commented 9 years ago

Hey, I fixed the tests. Sure I would be happy to keep contributing, there's some more features to do, and it needs tests for the 2.0 protocol. I will email you about ownership if you want to pass it on. Cheers

mcferren commented 9 years ago

Hi @sundbry Are you still planning on owning the v2 version of this library? A v2 version that we can use with Angular Wamp https://github.com/voryx/angular-wamp would be very helpful for a lot of people. I see the your PR was made in April. Do you have plans to release a stable version of clj-wamp with wampv2?

sundbry commented 9 years ago

@mcferren I've just pushed the last of my code to add support for progressive call results.. however my work stops there. I've stopped developing the project which was using this WAMP infrastructure. As far as I recall, the "callee" and "publisher" roles were completely implemented as per the WampV2 spec and I only skipped what were optional or "unstable" features of the protocol spec at the time, so you should have a sufficient implementation here at least.

The one thing really stopping me from calling it "stable enough" for a release is that I didn't develop a test suite for this new v2 code. My client-side application test cases at the time were sufficient for me to test the WAMP server implementation.

I think it's safe to merge this PR into master though and make a release out of it, after all, it shouldn't break backwards compatibility in the V1 (and there is a massive security hole in the V1 session ids which is fixed in this PR with 9fa38e6f9c1ba2daf0f1ac8ac838ea47033d5d73).

DoctorBud commented 8 years ago

Hello. I'm trying to use this PR branch for a WampV2 server and I noticed that server.clj is still using V1 message codes, and therefore doesn't work with V2. Looking through the commit history, I found a server-v2.clj, which seems to be what I want. However, it was deleted about 7 commits into the development of this branch: https://github.com/sundbry/clj-wamp/commit/5a5294e98fb53452be021d232252b171d40b3445

There is a node.clj that seems to be V2-aware, but only as a client.

I'm going to try to extract the deleted server-v2.clj and try to get that to work, but if @sundbry or anyone else has a clue here, it would save me some time.

I have a working V1 application (using the Legacy WampV1 AutobahnJS as my client), but I would love to be running WampV2 and my application is a good testbed for this PR, if I can get it working.

Thanks for any advice here.

sundbry commented 8 years ago

Hi @DoctorBud,

You want to construct the server using clj-wamp.node/create

The server-v2.clj was moved to v2.clj https://github.com/sundbry/clj-wamp/blob/master/src/clj_wamp/v2.cl

(wamp-node/create
  {:realm "default"   
   :router-uri "ws://localhost:1234/ws" ; Needs a wamp router, such as crossbar.io   
   :debug? true
   :on-call {...}})

Good luck, have fun; I stopped the project I was using this with, so development stopped, but I believe it is a pretty thorough implementation per the published specification.

On Thu, Feb 18, 2016 at 11:34 AM, Dan Keith notifications@github.com wrote:

Hello. I'm trying to use this PR branch for a WampV2 server and I noticed that server.clj is still using V1 message codes, and therefore doesn't work with V2. Looking through the commit history, I found a server-v2.clj, which seems to be what I want. However, it was deleted about 7 commits into the development of this branch: sundbry@5a5294e https://github.com/sundbry/clj-wamp/commit/5a5294e98fb53452be021d232252b171d40b3445

There is a node.clj that seems to be V2-aware, but only as a client.

I'm going to try to extract the deleted server-v2.clj and try to get that to work, but if @sundbry https://github.com/sundbry or anyone else has a clue here, it would save me some time.

I have a working V1 application (using the Legacy WampV1 AutobahnJS as my client), but I would love to be running WampV2 and my application is a good testbed for this PR, if I can get it working.

Thanks for any advice here.

— Reply to this email directly or view it on GitHub https://github.com/cgmartin/clj-wamp/pull/14#issuecomment-185882213.

DoctorBud commented 8 years ago

Thanks for the details, @sundbry. I see now that my V1 implementation was using WAMP in a way that seems to be deprecated, but quite practical. I am using the V1 server/http-kit-handler to allow my Clojure process to act as a WAMP router, as well as acting as a server application. For example:

    (defn my-wamp-handler [request]
      (wamp/with-channel-validation request channel #\"https?://myhost\"
        (wamp/http-kit-handler channel { ... })))

So my clients (Javascript in a browser) access my server via WAMP and then other components of my server (colocated in the same process) are reacting to incoming RPC messages which are relayed through core.async channels. The upside of this architecture is I have a single Clojure process. The downside is that it doesn't match the current WAMPv2 emphasis on separating the router from the application server From Wikipedia:

While routers can technically be embedded directly into the application code and some client libraries also provide a router, this architecture is discouraged by the specification.

So my options are to (1) adopt a Router component (crossbar.io) or (2) try to adapt server.clj to respect v2.clj's protocol code so that server.clj works with the WAMPV2. I think I'm going to give (2) a try, since it seems pretty close. It's probably a matter of ensuring that server.clj is using the correct protocol id wamp.2.json instead of wamp. Thanks again for your help and feel free to share any gotchas if you have the time.

sundbry commented 8 years ago

HI Dan,

I wouldn't recommend "ressurecting" that file, since the deleted code was mostly copy pasted out of the v1 implementation and the common stuff moved to core.clj, and the obsolete stuff deleted. There was also some security holes in there ( such as predictable session ids etc) that I fixed in the refactor to core.clj

As you can see in the HELLO message ( https://github.com/sundbry/clj-wamp/blob/master/src/clj_wamp/v2.clj#L86) the code only supports "callee" and "publisher" roles. The "dealer" role is left to the external router.

Implementing the dealer (as it's called in the spec, a/k/a router) should be as straightforward as adding the necessary handle-message multimethods for the messages that a dealer has to handle (CALL, SUBSCRIBE, etc) and then implementing the actual routing of course.

But IMHO, your time would be best served using a separate router, so you could get straight to writing your app!!! If you insist on keeping it all in one process though, maybe you could just launch a jawampa https://github.com/Matthias247/jawampa router thread in your program.

I do agree with you though, that the router seems like an unnecessary abstraction to force in.

Good luck have fun,

Ryan

On Thu, Feb 18, 2016 at 11:44 PM, Dan Keith notifications@github.com wrote:

Thanks for the details, @sundbry https://github.com/sundbry. I see now that my V1 implementation was using WAMP in a way that seems to be deprecated, but quite practical. I am using the V1 server/http-kit-handler to allow my Clojure process to act as a WAMP router, as well as acting as a server application. For example:

(defn my-wamp-handler [request]
  (wamp/with-channel-validation request channel #\"https?://myhost\"
    (wamp/http-kit-handler channel { ... })))

So my clients (Javascript in a browser) access my server via WAMP and then other components of my server (colocated in the same process) are reacting to incoming RPC messages which are relayed through core.async channels. The upside of this architecture is I have a single Clojure process. The downside is that it doesn't match the current WAMPv2 emphasis on separating the router from the application server From Wikipedia https://en.wikipedia.org/wiki/Web_Application_Messaging_Protocol#Routers :

While routers can technically be embedded directly into the application code and some client libraries also provide a router, this architecture is discouraged by the specification.

So my options are to (1) adopt a Router component (crossbar.io) or (2) try to resurrect server-v2.clj and adapt it to work with the WAMPV2 protocol code provided in node.clj. I think I'm going to give (2) a try, since it seems pretty close. Thanks again for your help and feel free to warn me away from this path.

— Reply to this email directly or view it on GitHub https://github.com/cgmartin/clj-wamp/pull/14#issuecomment-186105265.

DoctorBud commented 8 years ago

Since last posting here, I made a lot of progress.

I eventually succeeded in creating a version 2 server, sort of. You see, my application server (Scape) was built with V1’s idea that the server handlers could be hooked directly into the Wamp server, rather than the V2 pattern of having a Wamp router as a separate process from the participants. Having the WAMP handlers in-process with the WAMP server/router suits my needs and is probably more performant.

So I only proceeded far enough to get my Autobahn.JS (V2) client code to work, and it is working fine. I never completed full V2 Router functionality (although it may be there accidentally, I never tested it), since my handlers are still in-process with the Wamp server (a feature, not a bug). I was able to get the ‘wampcra’ authentication working.

The most recent branch that I’m using for my stuff is https://github.com/DoctorBud/clj-wamp/tree/version-2-server-with-example. I've yet to 'close the loop' and submit a PR back to the prime repo. Recently, @tuddman (https://github.com/tuddman) mentioned he was trying to progress the clj-wamp V2 version using my and others improvements to V1. So I added an example of an HTML/JS client connecting to a clj-wamp server via WAMP CRA (Challenge Response Authentication).

I hope that clj-wamp will continue to support the V1-compatible idea of in-process handlers, rather than requiring a separate specialized WAMP router/broker.

DoctorBud commented 8 years ago

Doh! I forgot to include instructions on how to run the test program.

To run the example server:

cd clj-wamp/
lein run -m example.main start

And then open the HTML file src/example/wstest.html in a browser.

The password will be the reverse of the username. E.g., FakeUser has password resUekaF. It's for demonstration purposes :)