init

WebSocket -- used in real-time data transfer scenarios, such as multiplayer games/ chatbots/ sensor network in IoT etc.

define

Well, WebSocket is simply a general HTTP connection with some modifications, where a normal HTTP connection gets upgraded to WebSocket connection, when two communicating PEERs agree to use a single socket for all their communication, followed by a handshake. It could be thought of as a bidirectional communication channel in between two PEERs. When communication ends, that socket is destroyed.

idea

May be you've already worked with WebSocket using NodeJS or Java or PHP or Python or something else, but today we're going to use Dart Language for implementing both WebSocket Server & Client in a much easier way.

Alright so let's get into coding ...

implement

First we're going to write a WebSocket Server

WebSocket Server

As I've already said, WebSocket is a modified version of a HTTP connection, we're going to create a HttpServer and then we'll upgrade that connection to WebSocket.



import 'dart:io' show HttpServer , HttpRequest ; main () { HttpServer . bind ( 'localhost' , 8000 ). then (( HttpServer server ) { // httpserver listens on http://localhost:8000 print ( '[+]HttpServer listening at -- http://localhost:8000' ); server . listen (( HttpRequest request ) { // more code goes here }, onError: ( err ) => print ( '[!]Error -- ${err.toString()} ' )); }, onError: ( err ) => print ( '[!]Error -- ${err.toString()} ' )); }

Now we've HttpRequest object, which is going to be upgraded to WebSocket.



import 'dart:io' show WebSocket , WebSocketTransformer ; import 'dart:convert' show json ; import 'dart:async' show Timer ; // will put this snippet with in main() WebSocketTransformer . upgrade ( request ). then (( WebSocket ws ) { // upgradation happens here and now we've a WebSocket object ws . listen ( // listening for data ( data ) { print ( ' \t\t ${request?.connectionInfo?.remoteAddress} -- ${Map<String, String>.from(json.decode(data))} ' ); // client will send JSON data Timer ( Duration ( seconds: 1 ), () { if ( ws . readyState == WebSocket . open ) ws . add ( json . encode ({ 'data' : 'from server at ${DateTime.now().toString()} ' , // in response JSON data is sent back to client })); // Timer helps to schedule code execution }); }, onDone: () => print ( '[+]Done :)' ), onError: ( err ) => print ( '[!]Error -- ${err.toString()} ' ), cancelOnError: true , ); }, onError: ( err ) => print ( '[!]Error -- ${err.toString()} ' ));

See it's this much easy to upgrade a HTTP connection to WebSocket connection, with Dart ❤️.

Here's our whole WebSocket Server code.



import 'dart:io' show HttpServer , HttpRequest , WebSocket , WebSocketTransformer ; import 'dart:convert' show json ; import 'dart:async' show Timer ; main () { HttpServer . bind ( 'localhost' , 8000 ). then (( HttpServer server ) { print ( '[+]WebSocket listening at -- ws://localhost:8000/' ); server . listen (( HttpRequest request ) { WebSocketTransformer . upgrade ( request ). then (( WebSocket ws ) { ws . listen ( ( data ) { print ( ' \t\t ${request?.connectionInfo?.remoteAddress} -- ${Map<String, String>.from(json.decode(data))} ' ); Timer ( Duration ( seconds: 1 ), () { if ( ws . readyState == WebSocket . open ) // checking connection state helps to avoid unprecedented errors ws . add ( json . encode ({ 'data' : 'from server at ${DateTime.now().toString()} ' , })); }); }, onDone: () => print ( '[+]Done :)' ), onError: ( err ) => print ( '[!]Error -- ${err.toString()} ' ), cancelOnError: true , ); }, onError: ( err ) => print ( '[!]Error -- ${err.toString()} ' )); }, onError: ( err ) => print ( '[!]Error -- ${err.toString()} ' )); }, onError: ( err ) => print ( '[!]Error -- ${err.toString()} ' )); }

Let's go for WebSocket Client.

WebSocket Client

Now Dart has got a class WebSocket in dart:io, which takes care of implementation of WebSocket Client, does all the heavy liftings for us ⚒️.

You can assume, implementation of WebSocket Client will be much easier.



import 'dart:io' show WebSocket ; import 'dart:convert' show json ; import 'dart:async' show Timer ; main () { WebSocket . connect ( 'ws://localhost:8000' ). then (( WebSocket ws ) { // our websocket server runs on ws://localhost:8000 if ( ws ?. readyState == WebSocket . open ) { // as soon as websocket is connected and ready for use, we can start talking to other end ws . add ( json . encode ({ 'data' : 'from client at ${DateTime.now().toString()} ' , })); // this is the JSON data format to be transmitted ws . listen ( // gives a StreamSubscription ( data ) { print ( ' \t\t -- ${Map<String, String>.from(json.decode(data))} ' ); // listen for incoming data and show when it arrives Timer ( Duration ( seconds: 1 ), () { if ( ws . readyState == WebSocket . open ) // checking whether connection is open or not, is required before writing anything on socket ws . add ( json . encode ({ 'data' : 'from client at ${DateTime.now().toString()} ' , })); }); }, onDone: () => print ( '[+]Done :)' ), onError: ( err ) => print ( '[!]Error -- ${err.toString()} ' ), cancelOnError: true , ); } else print ( '[!]Connection Denied' ); // in case, if serer is not running now }, onError: ( err ) => print ( '[!]Error -- ${err.toString()} ' )); }

Wasn't it easier than WebSocket Server implementation ?

And yes, with 930 bytes of client-side Dart code and 1175 bytes of server-side Dart code, we've completed WebSocket implementation.

run

Make sure you've installed Dart SDK from here and set PATH variable properly.

Time to run these beasts 😆



$ dart websocket_server.dart

And in another terminal



$ dart websocket_client.dart

And 💥

end

In this article, you've learnt how to use Dart for building WebSocket Peers, for tranferring real-time data.

Got any problems ? Yes Find me on Twitter

Wrap up time. See you in next article.

In the mean time, you may check out my GitHub profile for my other projects.