Home Sending websocket message from elsewhere in an Express.js app
Reply: 0

Sending websocket message from elsewhere in an Express.js app

Attila
1#
Attila Published in 2017-12-08 01:31:01Z

I'm using this ws library and have been able to correctly set up a websocket server and connection from a client.

I have all the logic inside of a class, and it looks like this (I've removed all business logic and other clutter that isn't really necessary, also please note that I'm using TypeScript):

import * as url from 'url';
import * as WebSocket from 'ws';

class Websocket {
    protected sitesObj: {};
    protected webSocketServer: any;

    public initConnections(server: any): void {
        this.webSocketServer = new WebSocket.Server({
            server,
            verifyClient: this.verifyClient.bind(this)
        });

        this.webSocketServer.on('connection', (webSocket: any, request: any): any => {
            // logic here to set up users and sites

            webSocket.send(`connected: ${userId} on site(s) ${siteId}`);
            webSocket.on('message', (message: any): any => {
                console.log('message from the client: ', message);
            });

            webSocket.on('close', (eventCode: any): any => {
                if (eventCode === 1006) {
                    console.log('Websocket disconnected abnormally');
                }
                if (eventCode === 1000) {
                    console.log('Websocket successfully closed normally');
                    // logic to remove user
                    webSocket.send(`deleted: ${userId} on site(s) ${siteId}`);
                }
            });
        });
    }

    public broadcast(data: any): any {
        this.webSocketServer.forEach((client: any): any => {
            client.send('test');
        });
    }

    private verifyClient(info: any, cb: any): any {
        // verification logic here
    }

}

const ws: Websocket = new Websocket();
export { ws };

There is an index file in this Express project (which is the entry point for the project) in which everything is essentially set up, including importing this ws class above. Once imported, this snippet runs: ws.initConnections(this.instance); where this.instance is the Express server. Clients can now attempt to connect to the websocket server and start sending and receiving messages.

My problem is, I cannot get the broadcast method to work in my app. I import this ws class into another part of my project, in which I want to trigger a broadcast. For example, in this other file I have:

import { ws } from '../../modules/websocket';
ws.broadcast('test');

However, this does not work. When the broadcast method is invoked, webSocketServer is undefined, and I'm not sure how I can target my stored websocket connections and send them messages through this method.

Here is the class in which the initConnections method is called, as request by @jfriend00 in the comments:

/**
 * @file Singleton server implementation.
 */

import * as express from 'express';
import * as http from 'http';

import { app } from './app';

import { ws } from '../modules/Websocket';

// Constants
const PORT: number = parseInt(process.env.PORT, 10);
const HOST: string = process.env.HOST;

/**
 * Http Server Implementation
 *
 * @export
 * @class Server
 */
export class Server {
    /* Local instances for access */
    public app: express.Application;
    public instance: http.Server;

    /**
     * Creates an instance of Server
     *
     * @memberof Server
     */
    constructor() {
        this.instance = http.createServer(app);
        this.app = app;
    }

    /**
     * Starts the http server
     *
     * @memberof Server
     */
    public start(port: number = null): void {
        const PORT_NUMBER: number = port || PORT;
        if (this.instance.address()) {
            logger.warn({
                action: 'ServiceStart',
                message: 'Server already started.', port: this.instance.address().port
            });
            return;
        }
        this.instance.listen(PORT_NUMBER, HOST);
        this.instance.on('listening', this.onListening);
        this.instance.on('error', this.onError);
        ws.initConnections(this.instance);
    }

    /**
     * Returns URL of the app service
     *
     * @memberof Server
     */
    public getAppServiceUrl(): string {
        /* TODO: get the proper protocol (will eventually be https) */
        /* tslint:disable-next-line */
        return `http://${HOST}:${PORT}`;
    }

    // ... plus a few other methods here

}

/**
 * @export
 * Singleton instance of http server
 */
const server: Server = new Server();
export { server };
You need to login account before you can post.

About| Privacy statement| Terms of Service| Advertising| Contact us| Help| Sitemap|
Processed in 0.53568 second(s) , Gzip On .

© 2016 Powered by mzan.com design MATCHINFO