websocket_channel_wrapper 1.1.4

  • Readme
  • Changelog
  • Example
  • Installing
  • 67

Wrapper for web_socket_channel package lightweight and isomorphic lib with socket.io-like event handling, Future-based requests. This wrapper implements the protocol for this ws node wrapper.

WARNING: server -> client requests are not sopported. If someone needs them open a PR

Usage #

A simple usage example:

Client side:

import 'dart:async';
import 'dart:io';
import 'package:websocket_channel_wrapper/websocket_channel_wrapper.dart';

const PORT = 42069;

main() {
  WebSocketChannelWrapper socket = WebSocketChannelWrapper('ws://192.168.0.18:$PORT',
                                              headers: {'id': '1234567890qwertyuiop'});

  print('Connecting...');

  var onReady = socket.onConnect.first;

  onReady.timeout(Duration(seconds: 5), onTimeout: () => print('Server could not be reach, trying to re-connect'));

  socket.onConnect.skip(1).listen((_) => print('Successful re-connection to server'));

  socket.onDone.listen((_) => print(socket.autoReconnect ? 'Connection lost, trying to re-connect!' : 'Connection ended!'));

  onReady.then((_) async { // [onConnect] It's called every time the WebSocket reconnect
    print('Connected!');

    socket.emit('msg', ['DART_WEBSOCKET_WRAPPER', 'Hello, World!']);

    socket.on('serverTime').listen((time) => print('Time: $time'));  // Time: 2019-07-29T14:00:32.635Z

    socket.request('userCount').then((n) => print('# users: $n'));   // # users: 1

    socket.request('checkError').catchError((e) => print(e));        // Yep, errors work

    var filename = '/path/to/file/image.jpg';
    sendFile(filename, socket);   // Send binary file over socket

    Timer(Duration(seconds: 10), () {    // Close the socket after 1 minute
      var reason = 'break time';
      print('Close reason: $reason');
      socket.close(closeReason: reason);
    });
  });
}

sendFile(String filename, socket) async {
  var image = File(filename);
  var contents = await image.readAsBytes();

  final stopwatch = Stopwatch()..start();   // Start timer to measure speed
  
  socket.request('transferFile', [filename, contents]).then((_) { // Send first file name then the bytes

    final speed = contents.length / stopwatch.elapsedMicroseconds;
    print('File sended in ${stopwatch.elapsed} at $speed MB/s');  // File sended in 0:00:00.058191 at 1.63 MB/s

  }).catchError((e) => print(e));
}


Server side:

const WebSocketServer = require("ws").Server
  , WebSocketWrapper = require("ws-wrapper")
const fs = require('fs')

const PORT = 42069

var wss = new WebSocketServer({port: PORT});
var sockets = new Set();

wss.on("connection", (sckt, req) => {
  const socket = new WebSocketWrapper(sckt)
  sockets.add(socket)

  console.log('New socket connected')
  socket.emit('serverTime', new Date())  // Send data to client on connect
  
  socket.on("msg", function(from, msg) {
      console.log(`Received message from ${from}: ${msg}`) // Received message from DART_WEBSOCKET_WRAPPER: Hello, World!
  });

  socket.on("userCount", () => {  // Request
  return sockets.size;
  });
  
  socket.on("checkError", () => { // Request rejecting the Promise
      throw 'Yep, errors work'
  })

  socket.on("transferFile", (filename, buffer) => {
    return new Promise((resolve, reject) => {
      fs.writeFile(filename, Buffer.from(buffer), function(err) { // Save binary data recieved to file
        if(err)
          reject(err)
        else{
          resolve(true)
          console.log('File received and saved!')
        }
      })
    })
  })

  socket.on("disconnect", (event) => {
      console.log(`REASON: ${event.reason} CODE: ${event.code}`) // REASON: break time    CODE: 1007
      sockets.delete(socket);
  });
})

console.log('Listening on port: ' + PORT)

1.1.4 #

  • Official support for binary files
  • Expose socket autoReconnect attribute
  • Default closeCode value is 1000 = NORMAL_CLOSURE

1.1.3 #

  • Fix bug on events stream e.g. onConnect & onDone
  • Improving example code

1.1.2 #

  • Pedantic dependencies fix for flutter

1.1.1 #

  • Bugfix on close method

1.1.0 #

  • Add auto-connect feature
  • Add onDone stream-events
  • Add onConnect stream-events, this includes reconnect events

1.0.1 #

  • Fix health package issues

1.0.0 #

  • Initial version, created by cTatu

example/websocket_channel_wrapper_example.dart

import 'dart:async';
import 'dart:io';
import 'package:websocket_channel_wrapper/websocket_channel_wrapper.dart';

const PORT = 42069;

main() {
  WebSocketChannelWrapper socket = WebSocketChannelWrapper('ws://192.168.0.18:$PORT',
                                              headers: {'id': '1234567890qwertyuiop'});

  print('Connecting...');

  var onReady = socket.onConnect.first;

  onReady.timeout(Duration(seconds: 5), onTimeout: () => print('Server could not be reach, trying to re-connect'));

  socket.onConnect.skip(1).listen((_) => print('Successful re-connection to server'));

  socket.onDone.listen((_) => print(socket.autoReconnect ? 'Connection lost, trying to re-connect!' : 'Connection ended!'));

  onReady.then((_) async { // [onConnect] It's called every time the WebSocket reconnect
    print('Connected!');

    socket.emit('msg', ['DART_WEBSOCKET_WRAPPER', 'Hello, World!']);

    socket.on('serverTime').listen((time) => print('Time: $time'));  // Time: 2019-07-29T14:00:32.635Z

    socket.request('userCount').then((n) => print('# users: $n'));   // # users: 1

    socket.request('checkError').catchError((e) => print(e));        // Yep, errors work

    var filename = '/path/to/file/image.jpg';
    sendFile(filename, socket);   // Send binary file over socket

    Timer(Duration(seconds: 10), () {    // Close the socket after 1 minute
      var reason = 'break time';
      print('Close reason: $reason');
      socket.close(closeReason: reason);
    });
  });
}

sendFile(String filename, socket) async {
  var image = File(filename);
  var contents = await image.readAsBytes();

  final stopwatch = Stopwatch()..start();   // Start timer to measure speed
  
  socket.request('transferFile', [filename, contents]).then((_) { // Send first file name then the bytes

    final speed = contents.length / stopwatch.elapsedMicroseconds;
    print('File sended in ${stopwatch.elapsed} at $speed MB/s');  // File sended in 0:00:00.058191 at 1.63 MB/s

  }).catchError((e) => print(e));
}

Use this package as a library

1. Depend on it

Add this to your package's pubspec.yaml file:


dependencies:
  websocket_channel_wrapper: ^1.1.4

2. Install it

You can install packages from the command line:

with pub:


$ pub get

with Flutter:


$ flutter pub get

Alternatively, your editor might support pub get or flutter pub get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:


import 'package:websocket_channel_wrapper/websocket_channel_wrapper.dart';
  
Popularity:
Describes how popular the package is relative to other packages. [more]
35
Health:
Code health derived from static analysis. [more]
100
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
100
Overall:
Weighted score of the above. [more]
67
Learn more about scoring.

We analyzed this package on Oct 23, 2019, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.5.1
  • pana: 0.12.21

Platforms

Detected platforms: Flutter, other

Primary library: package:websocket_channel_wrapper/websocket_channel_wrapper.dart with components: io.

Health suggestions

Format lib/src/websocket_channel_wrapper_base.dart.

Run dartfmt to format lib/src/websocket_channel_wrapper_base.dart.

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.2.0 <3.0.0
pedantic ^1.0.0 1.8.0+1
web_socket_channel ^1.0.14 1.1.0
Transitive dependencies
async 2.4.0
charcode 1.1.2
collection 1.14.12
convert 2.1.1
crypto 2.1.3
stream_channel 2.0.0
typed_data 1.1.6