Home

Awesome

Dropper

Dropper is a custom Event-driven WebSocket framework for Deno, using the deno-std ws module as base.

Send and receive notifications, messages, updates and any data, all in real-time with custom events and methods served on your own, Dropper is Open Source, self-served and FREE forever!

What can I do with Dropper?

Since Dropper is a WebSocket solution for transporting data between servers and clients, you can do whatever you need to go on real-time, like chat apps, trading, bots, database and website hot refreshs, etc. Its Side by Side APIs are designed to handle custom events sent by the application peers, you can work with the structured event handlers that allows to send and receive filtered data in a woshhh.

Quick Demo

The chat test on this repo lives on glitch, and you can test the app in production, but you can also run the demo on your local machine:

deno run -A https://deno.land/x/dropper@1.10.0/examples/chat/src/server.js

It will start a server on 8080 port

Importing

Server:

import { Server } from 'https://deno.land/x/dropper@1.10.0/src/mod.ts';
//or
import { Server } from 'https://x.nest.land/dropper@1.10.0/src/mod.ts'

Deno client:

You can import the client directly on your Deno app.

import Dropper from 'https://deno.land/x/dropper@1.10.0/src/mod.ts';
//or
import Dropper from 'https://x.nest.land/dropper@1.10.0/src/mod.ts'

Browser client

You can import this client on the browser in a module script.

import Dropper from 'https://deno.land/x/dropper@1.10.0/dist/clients/dropper.js';
//or
import Dropper from 'https://x.nest.land/dropper@1.10.0/dist/clients/dropper.js'

Usage

By default, you can use two instances of Dropper, the server and the client. The API is very similar to the EventEmitter API, but it is WebScoekts using on custom events.

Server:

The server waits for socket connections using the global event connection. This event gets the new connected socket on its callback. This socket represents a client so the API is the same as in the client side.

Stand alone server

Dropper is stand alone by default, which means that you don't need to provide an http server, when you create a dropper it serves by default on port 8080.

This is useful whe you are creating an app without a server side.


const options;

const dropper = new Server(options); // Creates a default server on port 8080

dropper.on('connection', socket => { // W
  socket.send('pizza', 'I sent you a pizza!')
  socket.on('thanks', data => {
    console.log(data) // => Thanks btw
  })
})

// Listening for global events

dropper.on('thanks', data => {
  console.log(data) // => Thanks btw
})

Middleware server

You can also use Dropper with a server/framework setup since it handles each request separately with the method Dropper.handle(req)

import { opine } from 'https://deno.land/x/opine/mod.ts'
const app = opine();
import { Server as Dropper } from '...'

const dropper = new Dropper({
  serve: false // Important
})

app.use('/dropper', (req) => dropper.handle(req)); // Don't respond or call next, just use the request.

app.get('/', (req, res) => {
  //...foo
})

dropper.on('connection', socket => {
  ..foo
})

app.listen(3000)

import { serve } from 'https://deno.land/std/http/server.ts'
import { Server as Dropper } from '...'

const server = serve('localhost:3000')

const dropper = new Dropper({
  serve: false // Important
})

dropper.on('connection', socket => {
  ..foo
})

for await (const req of server) {
  if (req.url === '/dropper') {
    dropper.handle(req);
  } else {
    // return static content, etc
  }
}

Please note that we use the /dropper endpoint on both of the examples. This is because we don't want to touch any usable endpoint, you can use whatever you want as endpoint, but you have to provide it in the Dropper client config object which is by default /dropper.

Options (optional)

API

Methods:

Properties:

Sending data to clients

You can send data to clients in three ways:

dropper.on('connection', socket => {
  socket.send('hello')
})

No one will receive this data except the current socket.

dropper.on('connection', socket => {
  socket.broadcast('hello')
})

All clients will receive the data except the current client.

dropper.send('hello')

All clients will receive the data .

Listening for client events

The event name for listening to all events is _all_

dropper.on('connection', socket => {
  socket.on('_all_', data => { // Listen for all events from this socket

  })
})

// or globally

dropper.on('_all_', ...foo)
...
socket.on('custom_event', ...foo) // Catch event just from the socket
...

dropper.on('custom_event', ...foo) // Catch event from all sockets

If the client send a no named event (client_side_dropper.send('no named')), you can listen to it with the event name message

...
socket.on('message', ...foo) // Catch no named event just from the socket
...

dropper.on('message', ...foo) // Catch no named event from all sockets

Handling disconnections from server

You can handle disconnections on two scopes:

From socket:

Handling disconnects from sockets only works if the socket is manually disconnected. It will not work if the client loses connection. The callback receives the same two arguments as in the client API (bellow).

dropper.on('connection', socket => {
  socket.on('close', (code, reason) => {
    //...foo
  })
})

From global

Handling global disconnects will listen to all clients that disconnect manually and also those that lose connection. The callback receives the same two arguments as in the client API (bellow) plus the disconnected socket as in the connection event.

dropper.on('disconnection', (code, reason, socket) => {
  //...foo
})

Reserved event senders

This is a list with the events you shouldn't play with:

Client

The client API connects to a server and it is a socket instance, so it has the same methods as the socket above.

Note: For creating clients on deno you can import Dropper from the main module, please don't use the Browser bundle.

const dropper = new Dropper(); // Connect the client on port 8080
dropper.on('pizza', function(data){
  console.log(data) // => I sent you a pizza!
  dropper.send('thanks', 'Thanks btw');
  dropper.close() // Closes the connection manually
});

dropper.on('close' => console.log('done'))

Connecting custom hosts

By default the Dropper clients connect to ws://localhost:8080 but you can change it by passing the host string as first param, you must specify if the connection is secure or not with the protocols ws || http for insecure connections or wss || https for secure connections.

const dropper = new Dropper('ws://localhost:3000'); // Connect the client on port 3000

// OR

const options = {
  endpoint: '/myDropperServerReservedEndpoint'
}

const dropper = new Dropper(`wss://${window.location.host}`, options); // Connects the client on the current host with a secure connection

Options (optional)

API

Methods:

Sending data to server

This is pushing a custom event to the server

dropper.send('pizza', 'this is a pizza')
dropper.broadcast('pizza', 'this is a pizza')

This is broadcasting a custom event to the server

This is pushing a no named event to the server

dropper.send('this is a pizza')

This is broadcasting a no named event to the server

dropper.broadcast('this is a pizza')

Listening for server events

This is listening a custom event from the server

dropper.on('pizza', data => {
  ...foo
})

This is listening a no named event from the server

dropper.on('message', data => {
  ...foo
})

Handling disconnections

To handle the socket disconnection you can use the close event. It only listen when the sockets disconnects itself.

dropper.on('close', (code, reason) => {
  ...foo
})

When a peer disconnects the server trigger the disconnection event that is useful for listening when other peers leave. It provides de uuid of the leaving socket.

dropper.on('disconnection', uuid => {
  ...foo
})

Reserved event senders

This is a list with the events you shouldn't play with:

Event collision warning

All the Dropper internal events has as prefix and suffix _. For example this is an internal event: _ping_, This is for preventing event collisions.

Building the web client

rollup -c

The documentation is WIP right now

By now, you can find detailed code in the examples folder.

📝 Roadmap

👊 Support this project by donating on:

📜 MIT License

Copyright (c) Crawford.

Full license