diff --git a/.npmignore b/.npmignore deleted file mode 100644 index 8eba6c8..0000000 --- a/.npmignore +++ /dev/null @@ -1 +0,0 @@ -src/ diff --git a/README.md b/README.md index 309651e..d64af56 100644 --- a/README.md +++ b/README.md @@ -1,108 +1,19 @@ -# express-ws [![Dependency Status](https://snyk.io/test/github/henningm/express-ws/badge.svg)](https://snyk.io/test/github/henningm/express-ws) - -[WebSocket](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API) endpoints for [Express](http://expressjs.com/) applications. Lets you define WebSocket endpoints like any other type of route, and applies regular Express middleware. The WebSocket support is implemented with the help of the [ws](https://github.com/websockets/ws) library. - -## Installation - -`npm install --save express-ws` - -## Usage - -__Full documentation can be found in the API section below. This section only shows a brief example.__ - -Add this line to your Express application: - -```javascript -var expressWs = require('express-ws')(app); -``` - -__Important: Make sure to set up the `express-ws` module like above *before* loading or defining your routers!__ Otherwise, `express-ws` won't get a chance to set up support for Express routers, and you might run into an error along the lines of `router.ws is not a function`. - -After setting up `express-ws`, you will be able to add WebSocket routes (almost) the same way you add other routes. The following snippet sets up a simple echo server at `/echo`. The `ws` parameter is an instance of the WebSocket class described [here](https://github.com/websockets/ws/blob/master/doc/ws.md#class-websocket). - -```javascript -app.ws('/echo', function(ws, req) { - ws.on('message', function(msg) { - ws.send(msg); - }); -}); -``` - -It works with routers, too, this time at `/ws-stuff/echo`: - -```javascript -var router = express.Router(); - -router.ws('/echo', function(ws, req) { - ws.on('message', function(msg) { - ws.send(msg); - }); -}); - -app.use("/ws-stuff", router); -``` - -## Full example +# +Only difference from [express-ws](https://snyk.io/test/github/henningm/express-ws) +is the method getWssClients(url) that fetchs clients of a given URL ```javascript -var express = require('express'); -var app = express(); -var expressWs = require('express-ws')(app); - -app.use(function (req, res, next) { - console.log('middleware'); - req.testing = 'testing'; - return next(); +app.ws('/a', function(ws, req) { }); -app.get('/', function(req, res, next){ - console.log('get route', req.testing); - res.end(); +app.ws('/b', function(ws, req) { }); -app.ws('/', function(ws, req) { - ws.on('message', function(msg) { - console.log(msg); - }); - console.log('socket', req.testing); -}); - -app.listen(3000); +//Fetch clients subscribed to route /a +const clientsA = expressWs.getWssClients("/a") +clientsA.forEach(client => {client.send("Hello clients from route /a")}) + +//Fetch clients subscribed to route /b +const clientsB = expressWs.getWssClients("/b") +clientsB.forEach(client => {client.send("Hello clients from route /b")}) ``` - -## API - -### expressWs(app, *server*, *options*) - -Sets up `express-ws` on the specified `app`. This will modify the global Router prototype for Express as well - see the `leaveRouterUntouched` option for more information on disabling this. - -* __app__: The Express application to set up `express-ws` on. -* __server__: *Optional.* When using a custom `http.Server`, you should pass it in here, so that `express-ws` can use it to set up the WebSocket upgrade handlers. If you don't specify a `server`, you will only be able to use it with the server that is created automatically when you call `app.listen`. -* __options__: *Optional.* An object containing further options. - * __leaveRouterUntouched:__ Set this to `true` to keep `express-ws` from modifying the Router prototype. You will have to manually `applyTo` every Router that you wish to make `.ws` available on, when this is enabled. - * __wsOptions:__ Options object passed to WebSocketServer constructor. Necessary for any ws specific features. - -This function will return a new `express-ws` API object, which will be referred to as `wsInstance` in the rest of the documentation. - -### wsInstance.app - -This property contains the `app` that `express-ws` was set up on. - -### wsInstance.getWss() - -Returns the underlying WebSocket server/handler. You can use `wsInstance.getWss().clients` to obtain a list of all the connected WebSocket clients for this server. - -Note that this list will include *all* clients, not just those for a specific route - this means that it's often *not* a good idea to use this for broadcasts, for example. - -### wsInstance.applyTo(router) - -Sets up `express-ws` on the given `router` (or other Router-like object). You will only need this in two scenarios: - -1. You have enabled `options.leaveRouterUntouched`, or -2. You are using a custom router that is not based on the express.Router prototype. - -In most cases, you won't need this at all. - -## Development - -This module is written in ES6 and uses ESM. diff --git a/examples/url-filter-broadcast.js b/examples/url-filter-broadcast.js new file mode 100644 index 0000000..566add9 --- /dev/null +++ b/examples/url-filter-broadcast.js @@ -0,0 +1,21 @@ +var express = require('express'); +var expressWs = require('..') + +var expressWs = expressWs(express()); +var app = expressWs.app; + +app.ws('/a', function(ws, req) { +}); + +app.ws('/b', function(ws, req) { +}); + +setInterval(function () { + const clientsA = expressWs.getWssClients("/a") + const clientsB = expressWs.getWssClients("/b") + + clientsA.forEach(client => {client.send("Hello clients from route /a")}) + clientsB.forEach(client => {client.send("Hello clients from route /b")}) +}, 5000); + +app.listen(3100) diff --git a/src/index.js b/src/index.js index dab6c66..510e6e7 100644 --- a/src/index.js +++ b/src/index.js @@ -43,6 +43,8 @@ export default function expressWs(app, httpServer, options = {}) { const wsServer = new ws.Server(wsOptions); wsServer.on('connection', (socket, request) => { + socket.wsUrl = request.url; + if ('upgradeReq' in socket) { request = socket.upgradeReq; } @@ -79,6 +81,14 @@ export default function expressWs(app, httpServer, options = {}) { getWss: function getWss() { return wsServer; }, + getWssClients: function getWssClients(url) { + if (!url) { + return wsServer.clients; + } + + const clients = Array.from(wsServer.clients); + return clients ? clients.filter((client) => client.wsUrl === url) : []; + }, applyTo: function applyTo(router) { addWsMethod(router); }