Wildhoney / EmberSockets

Socket.io (WebSockets) integrated with Ember.js' observer pattern.
http://ember-sockets.herokuapp.com/
MIT License
136 stars 22 forks source link

Access Socket in initialiser #38

Closed shopapps closed 10 years ago

shopapps commented 10 years ago

Hi, How can I access the socket in an initialiser, to check if it is connected and hence deferReadiness for the App? I have tried e.g. app/initializers/socket.js

export default {
    name:   'Socket',
    before: 'simple-auth',
    initialize: function(Container, App) {
        App.deferReadiness();

        /* Get Socket and check if connected ? */
        var controller = Container.lookup('controller:Application');
        var socket = controller.socket;
        console.log('[INITIALISER-SOCKET]',Container.lookup('controller:Chat'));
        console.log('[INITIALISER-SOCKET]', socket.socket.connected);
        if(socket.socket.connected)  App.advanceReadiness();
    }
};

and in app.js

var Socket = EmberSockets.extend({
    host: 'www.domain.com',
    port: 3000,
    controllers: ['index','chat','application'],
    autoConnect: true // defer connection until after Auth
});

But the above just gives 'socket is undefined' in the console. I also recognise I need some kind of loop looking for the socket.socket.connected... Thanks

Wildhoney commented 10 years ago

You could retrieve the instance from the Container using: Container.lookup('socket:main').

Also, to defer the connection until after auth, you'll need to define autoConnect as false, and then manually connect() yourself.

shopapps commented 10 years ago

Thanks for the quick response, I have just tried

var socket = Container.lookup('socket:main');
console.log('[INITIALISER-SOCKET]', socket);

but for some reason i still get 'socket is undefined'.

Wildhoney commented 10 years ago

Hmm... I am going to assume that your initializer is invoked before $ember.onLoad('Ember.Application', function($app) { ....

Could you connect to the WebSocket server in your ApplicationController once your user has been authenticated?

shopapps commented 10 years ago

Hi, This is using ember-cli (just in case it's critical info) and yes I could connect ok before.

I was manually connecting originally (after an Ajax Auth) and the socket was connecting OK, but I have now started to add models to my App (ember-data) and I want them to use the socket to collect/set data and I was running into timing issues with the socket not connecting fast enough, so decided to try and auto connect (autoConnect:true) the socket at the beginning (which is still fractionally too slow before the model tries to collect), so am now trying this deferedReadiness options to try and ensure the Socket is definitely connected before continuing to load the app..

shopapps commented 10 years ago

If the socket is not yet initialised, by the time the "initializers" are run, then there is little that can be done. I will after figure out another way around it. If that is the case then please close the ticket and I apologise for the hassle. BTW. I have written an adapter that uses ember-sockets for getting model data, is this of any use for you? ( i see you had a previous question/issue raised about it) it still needs a bit of work, how would be the best way of getting it to you (if you are interested)?

thanks for the help.

Wildhoney commented 10 years ago

Absolutely! Please open a pull request and merge it in. Do you think it would be suitable in the example directory?

shopapps commented 10 years ago

yeah I would have thought so (you could probably help tidy it up for me, but at least it would give you a starting point. I have not use git before, but I should be able to figure how to do a pull request... :-D

Wildhoney commented 10 years ago

Thanks! Let me know if you need any help :thumbsup: it would be great to get it merged into the example directory.

shopapps commented 10 years ago

hmm, is it possible to add a new file in a "pull request" when i try poking around it looks like I can setup a "diff" style discussion but only for existing files? Also this file is for 'ember-cli' i.e. it sits in app/adapters/application.js (in my case) so although it would be dead easy to convert I havent done that yet as I dont need to. Is there a way to push a file to you?

Wildhoney commented 10 years ago

You could take a look at the pull request guide on GitHub or if you'd like, send me the file to adam.timberlake@gmail.com, but it would be great to get an explanation from you as to how to use it, etc... – just needs a little bit of context to add to the README :thumbsup:

shopapps commented 10 years ago

ok will give it another

shopapps commented 10 years ago

hmm, perhaps you could create an empty file for me? something like example/app/adapters/application.js and then I can try to contribute/pull request to that file for you...

Wildhoney commented 10 years ago

Added :thumbsup:

shopapps commented 10 years ago

ok, so it looks like i need to fork the project first :-S doing that now.

shopapps commented 10 years ago

ok, looks like is done, can you see it? https://github.com/Wildhoney/EmberSockets/pull/39

Wildhoney commented 10 years ago

Yep, all merged! Would be nice to add something to the README.md as well to explain how to use your adapter. If you'd like to open a new pull request for this change?

shopapps commented 10 years ago

ok, I think i just figured out that a simple:

 this.socket = this.container.lookup('socket:Main').socket;

will get the socket am testing now, will let you know how i get on.

Wildhoney commented 10 years ago

:thumbsup:

shopapps commented 10 years ago

OK, so I have now come back to having to wait for the socket to connect before loading the App (I cant think of a better way around). I am now trying: app/initializers/socket.js

export default {
    name:   'Socket',
    initialize: function(Container, App) {
        App.deferReadiness();

        /* Get Socket and check if connected ? */

        App.register('socket:main', App.Socket, {
            singleton: true
        });
        App.inject('controller', 'socket', 'socket:main');
        App.inject('route', 'socket', 'socket:main');

        var socket = Container.lookup('socket:main');
        console.log('[SOCKET INIT] Socket: ', socket); // this does seem to echo the socket correctly

// this errors with socket.init does not exist??
        socket.init().connect().then(function(){
            App.advanceReadiness();
        });

    }
};

Is there a correct way to initialsie the socket module?

shopapps commented 10 years ago

ok, I think i solved it: app/initializers/socket.js the missing bit was after:'sockets', which makes this initializer run after ember-sockets meaning Container.lookup('socket:main'); works..

export default {
    name:   'Socket',
    after: 'sockets',
    initialize: function(Container, application) {
        application.deferReadiness();
        var socket = Container.lookup('socket:main');
        socket.connect();
        socket.socket.on('connect',function(){
            application.advanceReadiness();
        });
    }
};
Wildhoney commented 10 years ago

Perfect! Thanks for posting the solution, and good investigating :beers: