Skip to content
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

Connection events #11

Open
27leaves opened this issue Aug 21, 2017 · 10 comments
Open

Connection events #11

27leaves opened this issue Aug 21, 2017 · 10 comments

Comments

@27leaves
Copy link
Contributor

I'd need to get some connection state events, like in autobahn with onopen and onclose. Is this already possible with thruway?

@davidwdan
Copy link
Member

I haven't exposed open and close` because I haven't needed it yet and I'm not sure what the best way to expose it is. Thruway.js won't register or subscribe until the connection is established and if the connection resets, it'll reregister and resubscribe.

What is your use case?

@27leaves
Copy link
Contributor Author

My use cases are

  1. Tell the user when the app is offline (like, when his internet connection is down he should reconnect, else his actions have no effect
  2. On authorization, the connection will be closed when the token is invalid. In that case I want to be able to react to that.

@27leaves
Copy link
Contributor Author

Hi @davidwdan! Just wanted to check your thoughts on this feature :)

@davidwdan
Copy link
Member

@creat-or If a connection is closed because of an invalid token, that error should flow through to any of the subscribers on call, topic or register, so you should also be able to handle it there.

The options for connection events are:

  1. Pass a subject into the client constructor for onOpen, onClose, and onError
  2. Expose onOpen, onClose, and onError as methods on the client that return an observable

onError will only emit errors that occur before the session is established, like transport level errors and abort messages.

@davidwdan
Copy link
Member

@creat-or with the latest version you can now subscribe on open and close events:

    const ws = new WebSocketTransport("ws://127.0.0.1:9090");
    const wamp = new Client(ws, "realm1");

    ws.onOpen.subscribe(e=>console.log('open', e));
    ws.onClose.subscribe(e=>console.log('close', e));

Can you let me know if that works for you?

@27leaves
Copy link
Contributor Author

@davidwdan I'm sorry that it took that long to try the feature, I haven't worked on the project since then. In my usecase I have the following code

@Injectable()
export class WampService extends Client {

  constructor(private store: Store<fromAuth.State>) {
    super(
      (environment.production) ?
        'wss://' + location.host + '/router/' :
        'wss://myserver.com/router/',
      'gateway', {
      authmethods: ['ticket']
    });

    this.onChallenge(challenge => {
      // challenge logic
    });

    this.onOpen.subscribe(e=>console.log('log:open', e));
    this.onClose.subscribe(e=>console.log('log:close', e));
  }
}

onOpen works as expected, but onClose doesn't.

As you can see, I tried to bind to the onOpen & onClose sessions of the Client instead of the WebSocketTransport. That's because Typescript doesn't allow me to add anything before the super statement. I'm not sure if the onClose just works directly on the transport.

@voryx voryx deleted a comment from sutineeangs Nov 28, 2017
@27leaves
Copy link
Contributor Author

Hi David, just wanted to check if you could help me with my latest issue. I was busy with other projects meanwhile, but now I could use some help again ;) Thanks!

@27leaves
Copy link
Contributor Author

27leaves commented Feb 5, 2018

So, I got it to work. I had to handle the instantiation of the client myself to get to the WS events. This wasn't clear for me, so maybe we should update the documentation. If you need help with this I could help :)

Here is my working code:

@Injectable()
export class WampProvider {
  private ws: WebSocketTransport<any>;
  private client: Client;

  constructor(private store: Store<fromRoot.State>) {
    this.ws = new WebSocketTransport(
      localStorage.getItem('WAMP_URL') || SERVER_CONFIG[0].url,
      undefined,
      true
    );

    this.client = new Client(this.ws, 'gateway', { authmethods: ['ticket'] });

    this.client.onChallenge(challenge => {
      const ticketMethod = challenge.filter(msg => msg.authMethod === 'ticket');

      const token = this.store
        .select(fromRoot.getUser)
        .take(1)
        .map(user => user.token);

      return ticketMethod.mergeMapTo(token);
    });

    this.ws.onOpen.subscribe(event => {
      console.log('%c WampService: Connection Opened', 'color: #32db64');
      console.log(event);
      store.dispatch(new wamp.ConnectionOpen((event as any).details));
    });
    this.ws.onClose.subscribe(error => {
      console.log('%c WampService: Connection Closed(transport)', 'color: #f53d3d');
      console.log(error);
      store.dispatch(new wamp.ConnectionClose(error));
    });
    this.client.onClose.subscribe(error => {
      console.log('%c WampService: Connection Closed(client)', 'color: #f53d3d');
      console.log(error);
      store.dispatch(new wamp.ConnectionClose(error));
    })

    // As a workaround for https://github.com/voryx/thruway.js/issues/10.
    // This is still needed when I don't extend and inject the client via Angular,
    // but handle the instantiation myself with new Client(...).
    this.client.topic('cloud.connection.created').subscribe(); 
  }

  call(
    uri: string,
    args?: Array<any>,
    argskw?: Object,
    options?: CallOptions
  ): Observable<ResultMessage> {
    return this.client.call(uri, args, argskw, options);
  }

  topic (uri: string, options?: TopicOptions): Observable<EventMessage> {
    return this.client.topic(uri, options);
  }

  close() {
    this.client.close();
  }
  
  // some ngrx/store thingies, you don't have to care about them,
  // but I like that it's working ;)
  subscribeConnectedToStore(uri: string, action: string, addToResult: Object) {
    return this.client
      .topic(uri)
      .subscribe(result =>
        this.store.dispatch(
          new wamp.ReceivedEvent(action, { ...result.argskw, ...addToResult })
        )
      );
  }
}

@raires
Copy link

raires commented Dec 18, 2018

Is there any way to close the socket once open?

open() {
this.ws.open();
}

Then call an uri (fine up to this point. But when I try to close the connection it tries to reopen again.

this.client.close();
console result:
WampService: Connection Closed(transport)
wamp.ticket.O.service.ts:54
CloseEvent {isTrusted: true, wasClean: true, code: 1000, reason: "", type: "close", …} wamp.ticket.O.service.ts:54
The WebSocket connection was closed (anonymous) @ Client.js:72
Reconnecting Client.js:73
socket opened WebSocketTransport.js:82
WampService: Connection Opened wamp.ticket.O.service.ts:48
Event {isTrusted: true, type: "open", target: WebSocket, currentTarget: WebSocket, eventPhase: 2, …} wamp.ticket.O.service.ts:49

@andzejsw
Copy link

Is there any way to close the socket once open?

open() {
this.ws.open();
}

Then call an uri (fine up to this point. But when I try to close the connection it tries to reopen again.

this.client.close();
console result:
WampService: Connection Closed(transport)
wamp.ticket.O.service.ts:54
CloseEvent {isTrusted: true, wasClean: true, code: 1000, reason: "", type: "close", …} wamp.ticket.O.service.ts:54
The WebSocket connection was closed (anonymous) @ Client.js:72
Reconnecting Client.js:73
socket opened WebSocketTransport.js:82
WampService: Connection Opened wamp.ticket.O.service.ts:48
Event {isTrusted: true, type: "open", target: WebSocket, currentTarget: WebSocket, eventPhase: 2, …} wamp.ticket.O.service.ts:49

I know this is old question, but jeah..
I just added for Client WampOptions extra option:

            retryWhen: (attempts: Observable<Error>) => Observable.of({
                maxRetries: 0,
            }),

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants