npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

ember-websockets

v10.2.1

Published

EmberJS WebSockets addon for Ember-CLI apps.

Downloads

11,806

Readme

ember-websockets

GitHub Actions CI

Compatibility

  • Ember.js v3.24 or above
  • Ember CLI v3.24 or above
  • Node.js v12 or above

Installation

ember install ember-websockets

Usage

Simple example of using it in your app

import Controller from '@ember/controller';
import { inject as service } from '@ember/service';
import { action } from '@ember/object';

export default class MyController extends Controller {

  /*
   * 1. Inject the websockets service
   */
  @service('websockets') websockets;
  socketRef = null,

  constructor() {
    super(...arguments);

    /*
      2. The next step you need to do is to create your actual websocket. Calling socketFor
      will retrieve a cached websocket if one exists or in this case it
      will create a new one for us.
    */
    const socket = this.websockets.socketFor('ws://localhost:7000/');

    /*
      3. The next step is to define your event handlers. All event handlers
      are added via the `on` method and take 3 arguments: event name, callback
      function, and the context in which to invoke the callback. All 3 arguments
      are required.
    */
    socket.on('open', this.myOpenHandler, this);
    socket.on('message', this.myMessageHandler, this);
    socket.on('close', this.myCloseHandler, this);

    this.set('socketRef', socket);
  }

  myOpenHandler(event) {
    console.log(`On open event has been called: ${event}`);
  }

  myMessageHandler(event) {
    console.log(`Message: ${event.data}`);
  }

  myCloseHandler(event) {
    console.log(`On close event has been called: ${event}`);
  }

  @action
  sendButtonPressed() {
    this.socketRef.send('Hello Websocket World');
  }
}

Sending messages to the server

const socket = this.socketService.socketFor('ws://localhost:7000/');
socket.send({username: 'foo', didSomeAction: 'pressedAButton'}, true);

// the above line is the same as this:
socket.send(JSON.stringify({username: 'foo', didSomeAction: 'pressedAButton'}));

The send method takes 2 arguments. A message which is passed into the native websockets send method and an optional stringify boolean. This boolean, if set to true, will do a JSON.stringify to the message before passing it to the websocket send method. If you are sending strings it is recommended to pass true.

Reconnecting

import Controller from '@ember/controller';
import { inject as service } from '@ember/service';
import { later } from '@ember/runloop';

export default class MyController extends Controller {
  @service('websockets') socketService;

  constructor() {
    super(...arguments);

    const socket = this.socketService.socketFor('ws://localhost:7000/');
    socket.on('close', this.myOnClose, this);
  }

  myOnClose() {
    const socket = this.socketService.socketFor('ws://localhost:7000/');
    later(this, () => {
      /*
        This will remove the old socket and try and connect to a new one on the same url.
        NOTE: that this does not need to be in a Ember.run.later this is just an example on
        how to reconnect every second.
      */
      socket.reconnect();
    }, 1000);
  }
}

Closing the connection

import Component from '@ember/component';
import { inject as service } from '@ember/service';

export default class MyComponent extends Component {
  @service('websockets') socketService;

  /*
    To close a websocket connection simply call the closeSocketFor method. NOTE: it is good
    practice to close any connections after you are no longer in need of it. A good
    place for this clean up is in the willDestroyElement method of the object.
  */
  willDestroyElement() {
    this.socketService.closeSocketFor('ws://localhost:7000/');
  }
}

Multiple Websockets

import Component from '@ember/component';
import { inject as service } from '@ember/service';

export default class MyComponent extends Component {
  @service('websockets') socketService;

  didInsertElement() {
    const socketOne = this.socketService.socketFor('ws://localhost:7000/');
    const socketTwo = this.socketService.socketFor('ws://localhost:7001/');

    socketOne.on('open', this.myOpenFirst, this);
    socketTwo.on('open', this.myOpenSeconds, this);
  }

  myOpenFirst(event) {
    console.log('Hello from socket one');
  }

  myOpenSecond(event) {
    console.log('Hello from socket two');
  }

  willDestroyElement() {
    const socketOne = this.socketService.socketFor('ws://localhost:7000/');
    const socketTwo = this.socketService.socketFor('ws://localhost:7001/');
    socketOne.off('open', this.myOpenFirst);
    socketTwo.off('open', this.myOpenSecond);
  }
}

Multiple Event Handlers

import Component from '@ember/component';
import { inject as service } from '@ember/service';

export default class MyComponent extends Component {
  socketService: service('websockets'),

  didInsertElement() {
    const socket = this.socketService.socketFor('ws://localhost:7000/');

    socket.on('open', this.myOpenFirst, this);
    socket.on('open', this.myOpenSecond, this);
  }

  myOpenFirst() {
    console.log('This will be called');
  }

  myOpenSecond() {
    console.log('This will also be called');
  }

  willDestroyElement() {
    const socket = this.socketService.socketFor('ws://localhost:7000/');
    socket.off('open', this.myOpenFirst);
    socket.off('open', this.myOpenSecond);
  }
}

Socket.IO Support

First set socketIO to be true in your config/environment.js file:

var ENV = {
  'ember-websockets': {
    socketIO: true
  }
};
import Component from '@ember/component';
import { inject as service } from '@ember/service';

export default class MyComponent extends Component {

  /*
    1. Inject the socketio service
  */
  @service('socket-io') socketIOService;

  /*
    Important note: The namespace is an implementation detail of the Socket.IO protocol...
    http://socket.io/docs/rooms-and-namespaces/#custom-namespaces
  */
  namespace = 'myCustomNamespace',

  didInsertElement() {
    /*
      2. The next step you need to do is to create your actual socketIO.
    */
    const socket = this.socketIOService.socketFor(`http://localhost:7000/${this.namespace}`);

    /*
    * 3. Define any event handlers
    */
    socket.on('connect', this.onConnect, this);
    socket.on('message', this.onMessage, this);

    /*
      4. It is also possible to set event handlers on specific events
    */
    socket.on('myCustomEvent', () => { socket.emit('anotherCustomEvent', 'some data'); });
  }

  onConnect() {
    const socket = this.socketIOService.socketFor(`http://localhost:7000/${this.namespace}`);

    /*
      There are 2 ways to send messages to the server: send and emit
    */
    socket.send('Hello World');
    socket.emit('Hello server');
  }

  onMessage(data) {
    // This is executed within the ember run loop
  }

  myCustomEvent(data) {
    const socket = this.socketIOService.socketFor(`http://localhost:7000/${this.namespace}`);
    socket.emit('anotherCustomEvent', 'some data');
  }

  willDestroyElement() {
    const socket = this.socketIOService.socketFor(`http://localhost:7000/${this.namespace}`);
    socket.off('connect', this.onConnect);
    socket.off('message', this.onMessage);
    socket.off('myCustomEvent', this.myCustomEvent);
  }
}

Please visit: socket.io docs for more details on ember-websocket + socket.io

Detailed explanations of the APIs

SocketFor

Example:

const socket = this.socketService.socketFor('ws://localhost:7000/', ['myOptionalProtocol']);

socketFor takes two arguments: a url, a protocol array (optional), and returns a socket instance from its cache or a new websocket connection if one was not found.

To use a custom namespace, append the namespace to the end of the url.

const socket = this.socketService.socketFor(`ws://localhost:7000/${namespace}`);

On

Example:

const socket = this.socketService.socketFor('ws://localhost:7000/');

socket.on('open', this.myOtherOpenFunction);

on takes 3 arguments: event type, callback function, and context. Event type can be one of the following: 'open', 'message', 'close', and 'error'. Callback function will be invoked when one of the event types occurs.

Off

Example:

const socket = this.socketService.socketFor('ws://localhost:7000/');

let openFunctionReference = this.myOpenFunction.bind(this);

socket.on('open', openFunctionReference);
socket.off('open', openFunctionReference);

off takes 2 arguments: event type, callback function. Event type can be one of the following: 'open', 'message', 'close', and 'error'. The callback will be removed from the event pool and will no longer be invoked.

CloseSocketFor

Example:

this.socketService.closeSocketFor('ws://localhost:7000/');

closeSocketFor takes a single argument, a url, and closes the websocket connection. It will also remove it from the cache. In normal cases you would not have to call this method.

Reconnect

Example:

socket.on('close', event => {
  socket.reconnect();
});

reconnect takes no arguments. It will attempt to create a new websocket connect using the previous url. If the connect is not successful the close event will be triggered.

Live Example

  • git clone [email protected]:thoov/ember-websockets.git
  • cd ember-websockets
  • yarn
  • ember s
  • Then visit http://localhost:4200/sockets/example to view a very simple example.

The source code for the live example lives in ember-websockets/tests/dummy

Running tests

  • git clone [email protected]:thoov/ember-websockets.git
  • cd ember-websockets
  • yarn
  • ember t
  • or ember s then visit http://localhost:4200/tests to view the tests.

NOTE: To get the test to run in PhantomJS I created a mocking library found here: mocking library Note that it is still a work in progress.

Feedback or issues

If you have any feedback, encounter any bugs, or just have a question, please feel free to create a github issue or send me a tweet at @thoov.

FAQ

Recommended backend library/framework

Contributing

See the Contributing guide for details.

License

This project is licensed under the MIT License.