README.md

# WAMPexClient

WAMPexClient is a client library for the [WAMP protocol](https://wamp-proto.org/index.html). It pairs quite nicely with [WAMPexRouter](https://gitlab.com/entropealabs/wampex_router).

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

Transport support is currently only available over WebSocket

MessagePack and JSON serialization are both supported

## Basic Profile

### Session
- [x] HELLO
- [x] WELCOME
- [x] ABORT
- [x] GOODBYE
- [x] ERROR

### PubSub
- [x] SUBSCRIBE
- [x] SUBSCRIBED
- [x] UNSUBSCRIBE
- [x] UNSUBSCRIBED
- [x] PUBLISH
- [x] PUBLISHED
- [x] EVENT

### RPC
- [x] REGISTER
- [x] REGISTERED
- [x] UNREGISTER
- [x] UNREGISTERED
- [x] CALL
- [x] INVOCATION
- [x] YIELD
- [x] RESULT

## 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

### PubSub
- [ ] subscriber_blackwhite_listing
- [ ] publisher_exclusion
- [ ] publisher_identification
- [ ] publication_trustlevels
- [ ] subscription_meta_api
- [ ] pattern_based_subscription
- [ ] sharded_subscription
- [ ] event_history
- [ ] topic_reflection

### Other
- [x] challenge-response authentication
- [ ] cookie authentication
- [ ] ticket authentication
- [ ] rawsocket transport
- [ ] batched WS transport
- [ ] longpoll transport
- [ ] session meta api


## 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_client,
       git: "https://gitlab.com/entropealabs/wampex_client",
       tag: "5c8b95114bfc11b8c9ce92803f22c088b34a78eb"}
  ]
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.{Realm, Session}
alias Wampex.Role.{Callee, Caller, Publisher, Subscriber}

url = "http://localhost:4000/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.Client.Realm
alias Wampex.Role.{Callee, Caller, Publisher, Subscriber}
alias Wampex.Serializer.JSON
alias Wampex.Client.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


_COMING SOON_

Happy hacking ;)