-# WAMPex
+# WAMPexRouter
-WAMPex is a client library for the [WAMP protocol](https://wamp-proto.org/index.html)
+A highly scalable WAMP Router implementing the Broker and Dealer roles.
-This client library currently implements the [Basic Profile](https://wamp-proto.org/_static/gen/wamp_latest.html#basic-and-advanced-profiles) and some features of the Advanced Profile
+Utilizes distributed Erlang for a full mesh distributed cluster.
-Transport support is currently only available over WebSocket
+Under the hood it's using [ClusterKV](https://gitlab.com/entropealabs/cluster_kv) to provide an ephemeral distributed hash table key-value store.
-MessagePack and JSON serialization are both supported
+ClusterKV utilizes [libring](https://github.com/bitwalker/libring) and [libcluster](https://github.com/bitwalker/libcluster) from [bitwalker](https://github.com/bitwalker/) to provide the hash table or "ring" and dynamic clustering, respectively.
-## Basic Profile
+This is used for session level things like subscriptions and registrations.
-### Session
-- [x] HELLO
-- [x] WELCOME
-- [x] ABORT
-- [x] GOODBYE
-- [x] ERROR
+For persistant data such as users, realms, roles, device shadows, etc it utilizes CockroachDB. It uses the ecto and the postgres driver, so it should be compatible with a Postgresql server as well (not tested).
-### PubSub
-- [x] SUBSCRIBE
-- [x] SUBSCRIBED
-- [x] UNSUBSCRIBE
-- [x] UNSUBSCRIBED
-- [x] PUBLISH
-- [x] PUBLISHED
-- [x] EVENT
+The Basic Profile is fully supported, as is "wampcra" authentication. In fact, you must authenticate in order to interact with the server.
-### RPC
-- [x] REGISTER
-- [x] REGISTERED
-- [x] UNREGISTER
-- [x] UNREGISTERED
-- [x] CALL
-- [x] INVOCATION
-- [x] YIELD
-- [x] RESULT
+There are several admin routes available by default to create users and roles. `admin.create_user` and `admin_create_realm`
## Advanced Profile
-### Authentication
-- [x] CHALLENGE
-- [x] AUTHENTICATE
-### RPC
-- [X] CANCEL
-- [X] INTERRUPT
-- [x] Progressive Call Results
-- [x] Progressive Calls
-- [x] Call Canceling
-- [ ] call_timeout
-- [ ] caller_identification
-- [ ] call_trustlevels
-- [ ] registration_meta_api
-- [ ] pattern_based_registration
-- [ ] shared_registration
-- [ ] sharded_registration
-- [ ] registration_revocation
-- [ ] procedure_reflection
+In addition to authentication, prefix and pattern matching are also supported for PubSub subscriptions.
-### PubSub
-- [ ] subscriber_blackwhite_listing
-- [ ] publisher_exclusion
-- [ ] publisher_identification
-- [ ] publication_trustlevels
-- [ ] subscription_meta_api
-- [ ] pattern_based_subscription
-- [ ] sharded_subscription
-- [ ] event_history
-- [ ] topic_reflection
+Initial support for progressive call results for RPC is also available.
-### Other
-- [x] challenge-response authentication
-- [ ] cookie authentication
-- [ ] ticket authentication
-- [ ] rawsocket transport
-- [ ] batched WS transport
-- [ ] longpoll transport
-- [ ] session meta api
+More coming soon!
-
-## Installation
-
-Currently it's not available on hex.pm. I want to get a little more real-world testing done before committing to the implementation. However, it is available on Gitlab. You can add the following to your `mix.exs` file to use it.
-
-```elixir
-def deps do
- [
- {:wampex,
- git: "https://gitlab.com/entropealabs/wampex",
- tag: "101190dacd9e33f6f445c98c9b5d9e2995d84a93"}
- ]
-end
-```
-
-## Documentation
-
-The package isn't published to hex yet, so to view the docs you'll need to check out the repo and run `mix docs`.
-
-Module documentation is light at the moment, but everything has specs and passes Dialyzer testing.
-
-## Usage
-
-You can see a full example app, emulating a Smart Home and backend system [here](https://gitlab.com/entropealabs/wampex_example_app)
-
-Currently the only transport supported is WebSockets, but raw TCP is planned for the near future.
-
-WAMPex defaults to WebSocket as the transport and MessagePack as the serialization format.
-
-A simple [Session](https://wamp-proto.org/_static/gen/wamp_latest.html#sessions) can be configured like so.
-
-```elixir
-alias Wampex.Client.Session
-alias Wampex.Realm
-alias Wampex.Role.{Callee, Caller, Publisher, Subscriber}
-
-url = "http://localhost:18080/ws"
-realm = %Realm{name: "com.myrealm"}
-
-roles = [Callee, Caller, Publisher, Subscriber]
-session = %Session{url: url, realm: realm, roles: roles}
-
-Wampex.Client.start_link(name: Connection, session: session)
-```
-
-The name can be anything you want, it is required, and must be unique among multiple WAMPex instances. See the [example application](https://gitlab.com/entropealabs/wampex_example_app) for an example of running multiple connections/sessions.
-
-There are behaviours for transports and serializers if you wanted to write your own.
-
-You can override the default serializer and transport like this.
-
-```elixir
-alias Wampex.Client.Session
-alias Wampex.Realm
-alias Wampex.Role.{Callee, Caller, Publisher, Subscriber}
-alias Wampex.Serializer.JSON
-alias Wampex.Transport.WebSocket
-
-url = "http://localhost:18080/ws"
-realm = %Realm{name: "com.myrealm"}
-
-roles = [Callee, Caller, Publisher, Subscriber]
-session = %Session{url: url, realm: realm, roles: roles, protocol: "wamp.2.json", serializer: JSON}
-
-Wampex.Client.start_link(name: Connection, session: session)
-```
-
-The protocol uses a registered [WebSocket subprotocol](https://wamp-proto.org/_static/gen/wamp_latest.html#websocket-transport), there are several values available. You need to ensure that the [Router](https://wamp-proto.org/_static/gen/wamp_latest.html#peers-and-roles) that you connect to also supports the subprotocol.
-
-### Implementation Details
-
-WAMPex currently maps each session to a seperate transport connection. This means there is a new connection per instance of WAMPex.
-
-Internally WAMPex uses [Registry](https://hexdocs.pm/elixir/Registry.html#module-using-as-a-pubsub) for local PubSub. Subscriptions and Callees are registered with separate Registry instances, partitioned over the available system CPU cores.
-
-The Session management is handled by a state machine, written using [StatesLanguage](https://github.com/citybaseinc/states_language). You can view the specification in [priv/session.json](priv/session.json).
-
-You can copy and paste the JSON into the JSON input at https://citybaseinc.github.io/states-language-editor/ to edit and visualize the state machine.
-
-## Local Development
-
-You'll need compliant WAMP Router to run the tests, and do development in general. I recommend the [Bondy Router](https://gitlab.com/leapsight/bondy), it's written in Erlang.
-
-There's a Docker image available, so we'll use that to get up and running quickly.
-
-Make sure you are in the `wampex` directory before running this command.
-
-```bash
-docker run \
- -p 18080:18080 \
- -p 18081:18081 \
- -p 18082:18082 \
- -p 18086:18086 \
- -v $PWD/bondy_config:/bondy/etc \
- -d leapsight/bondy:0.8.8-slim
-```
-
-### Configure Realm
-
-```bash
-curl -X "POST" "http://localhost:18081/realms/" \
- -H 'Content-Type: application/json; charset=utf-8' \
- -H 'Accept: application/json; charset=utf-8' \
- -d $'{
- "uri": "com.myrealm",
- "description": "Test",
- "security_enabled" : false
-}'
-```
-
-This will setup a default realm `com.myrealm`.
-
-This config allows anonymous users as well as authenticated ones. In reality you wouldn't want to enable both, but for testing, it's useful.
-
-Now we need to add our user for testing authentication.
-
-```bash
-curl -X "POST" "http://localhost:18081/realms/com.myrealm/users" \
- -H 'Content-Type: application/json; charset=utf-8' \
- -H 'Accept: application/json; charset=utf-8' \
- -d $'{
- "username": "entone",
- "password": "test1234"
-}'
-```
-
-### Run the tests
-
-Warning as errors, mix format, Dialyzer, Credo and Coveralls
-
-```bash
-$ MIX_ENV=test mix all_tests
-```
-
-The Router uses CockroachDB
-
-```bash
-$ docker run -p 26257:26257 -p 8080:8080 cockroachdb/cockroach-unstable:v20.1.0-beta.2 start-single-node --insecure
-```
-
-Happy hacking ;)