How you can use WebSockets with Flutter
Posted by Superadmin on January 31 2023 12:32:08

How you can use WebSockets with Flutter

 

 

 

WebSockets are clearly taking the industry by storm. With Google's Flutter framework on the rise too, it would give you a big boost knowing how to integrate both of these technologies.

What are WebSockets

image

WebSockets represent a long-awaited evolution in the client/server web technology. It defines a fully duplex bi-directional communication channel between the client and server.

Related:
What do you mean by client and a server?

In simple words, once after the initial handshake where the server and the client agree to upgrade to WebSockets, (from HTTP) the client and the server can talk in real time without having to continuously make requests (like loading the page again and again).

Only the client-side problems of developing a dependable WebSocket-based solution for realtime Flutter apps are discussed in this article. On the server side, you must determine which solution you wish to utilise. You can use an open-source library like Socket.IO if you haven't already.

How to connect to a WebSocket server with Flutter

web_socket_channel package

We will use this package to acquire the tools we need to connect to a WebSocket server.
image

In short words, the package allows you to both listen for messages from the server and push messages to the server i.e fully duplex bi-directional communication channel.

Installation
Follow the installation given here:
https://pub.dev/packages/web_socket_channel/install

Basic Idea

image

Here is the boiler plate we will be using:

  import 'package:flutter/material.dart';
  import 'package:web_socket_channel/web_socket_channel.dart';
  import 'package:web_socket_channel/io.dart';
   
  void main() => runApp(new MyApp());
   
  class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
  return MaterialApp(
  home: MyHomePage(),
  );
  }
  }
   
  class MyHomePage extends StatefulWidget {
   
  @override
  MyHomePageState createState() {
  return MyHomePageState();
  }
  }
   
  class MyHomePageState extends State<MyHomePage> {
  TextEditingController _controller = TextEditingController();
  @override
  Widget build(BuildContext context) {
  return Scaffold(
  appBar: AppBar(
  title: Text("WebSocket Example"),
  ),
  body: Padding(
  padding: const EdgeInsets.all(20.0),
  child: Column(
  crossAxisAlignment: CrossAxisAlignment.start,
  children: <Widget>[
  Form(
  child: TextFormField(
  decoration: InputDecoration(labelText: "Send message to the server"),
  controller: _controller,
  ),
  ),
  ],
  ),
  ),
  floatingActionButton: FloatingActionButton(
  child: Icon(Icons.send),
  onPressed: sendData,
  ),
  );
  }
  }
view rawmain.dart hosted with ❤ by GitHub

How to connect to server

First let us connect to a WebSocket server. As discussed above we will be using an echo webSocket server.

WebSocketChannel channel = IOWebSocketChannel.connect("wss://ws.ifelse.io/");
  class MyHomePage extends StatefulWidget {
  WebSocketChannel channel = IOWebSocketChannel.connect("wss://ws.ifelse.io/");
   
  @override
  MyHomePageState createState() {
  return MyHomePageState();
  }
  }
  class MyHomePageState extends State<MyHomePage> {
  TextEditingController _controller = TextEditingController();
  @override
  Widget build(BuildContext context) {
  //.....same code as gist (1)
view rawmain.dart hosted with ❤ by GitHub

How to listen to the server

image

StreamBuilder(  
  stream: widget.channel.stream,  
  builder: (context, snapshot) {  
    return Padding(  
      padding: const EdgeInsets.all(20.0),  
  child: Text(snapshot.hasData ? '${snapshot.data}' : ''),  
  );  
  },  
)

Watch this video to get a better idea about StreamBuilder:

How to Send data to the server

image

We will add a function sendData() responsible for sending data to the stream whenever the floating button is pressed.

void sendData() {  
  if (_controller.text.isNotEmpty) {  
    widget.channel.sink.add(_controller.text);  
  }  
}

How to close the connection?

Using the close method we can disconnect from the server.

void dispose() {  
  widget.channel.sink.close();  
 super.dispose();  
}

Final Code

  import 'package:flutter/material.dart';
  import 'package:web_socket_channel/web_socket_channel.dart';
  import 'package:web_socket_channel/io.dart';
   
  void main() => runApp(new MyApp());
   
  class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
  return MaterialApp(
  home: MyHomePage(),
  );
  }
  }
   
  class MyHomePage extends StatefulWidget {
  WebSocketChannel channel = IOWebSocketChannel.connect("wss://ws.ifelse.io/");
   
  @override
  MyHomePageState createState() {
  return MyHomePageState();
  }
  }
   
  class MyHomePageState extends State<MyHomePage> {
  TextEditingController _controller = TextEditingController();
  @override
  Widget build(BuildContext context) {
  return Scaffold(
  appBar: AppBar(
  title: Text("Web Socket"),
  ),
  body: Padding(
  padding: const EdgeInsets.all(20.0),
  child: Column(
  crossAxisAlignment: CrossAxisAlignment.start,
  children: <Widget>[
  Form(
  child: TextFormField(
  decoration: InputDecoration(labelText: "Send any message to the server"),
  controller: _controller,
  ),
  ),
  StreamBuilder(
  stream: widget.channel.stream,
  builder: (context, snapshot) {
  return Padding(
  padding: const EdgeInsets.all(20.0),
  child: Text(snapshot.hasData ? '${snapshot.data}' : ''),
  );
  },
  )
  ],
  ),
  ),
  floatingActionButton: FloatingActionButton(
  child: Icon(Icons.send),
  onPressed: sendData,
  ),
  );
  }
   
  void sendData() {
  if (_controller.text.isNotEmpty) {
  widget.channel.sink.add(_controller.text);
  }
  }
   
  @override
  void dispose() {
  widget.channel.sink.close();
  super.dispose();
  }
  }
view rawmain.dart hosted with ❤ by GitHub

If you successfully connected to the server then you would see this on the emulator.
image

This is how your app should look at the end:

Animation

 

Where can you use it?

The realtime web existed before WebSockets, but it was difficult to accomplish, often slower, and based on hacking web technologies that weren't built for realtime applications. The WebSocket protocol paved the path for a genuinely real-time web and expanded the possibilities of Internet communication.

USE CASES: