Blog Details

img
Development

Flutter – WebSockets

Spoke Right / 1 Nov, 2023

WebSockets are used to connect with the server just like the http package. It supports two-way communication with a server without polling.

In this article we will explore the below-listed topics related to WebSockets in Flutter:

  1. Connecting to a WebSocket server
  2. Listen to messages from the server.
  3. Send data to the server.
  4. Close the WebSocket connection.

In this article as an example, we will connect to the test server provided by websocket.org.

Connect to a WebSocket Server:

The web_socket_channel package has tools that are needed to connect to a WebSocket server. The package provides a WebSocketChannel that allows users to both listen to messages from the server and push messages to the server.

In Flutter, use the following line to create a WebSocketChannel that connects to a server:

final channel = IOWebSocketChannel.connect('ws://echo.websocket.org');

Listen to messages from the server:

Now that we have established the connection to the server, we will send a message to it and get the same message as a response:

  • Dart




StreamBuilder(

  stream: widget.channel.stream,

  builder: (context, snapshot) {

    return Text(snapshot.hasData ? '${snapshot.data}' : '');

  },

);

Send Data to the Server:

To send data to the server, add() messages to the sink provided by the WebSocketChannel as shown below:

channel.sink.add('Hello Geeks!');

Close the Connection:

To close the connection to the WebSocket use the below:

channel.sink.close();

Complete Source Code:

  • Dart




import 'dart:async';

import 'dart:convert';

  

import 'package:flutter/material.dart';

import 'package:http/http.dart' as http;

  

Future fetchAlbum() async {

  final response =

  await http.get('https://jsonplaceholder.typicode.com/albums/1');

  

  if (response.statusCode == 200) {

    return Album.fromJson(json.decode(response.body));

  } else {

    throw Exception('Loading album failed!');

  }

}

  

Future updateAlbum(String title) async {

  final http.Response response = await http.put(

    'https://jsonplaceholder.typicode.com/albums/1',

    headers: {

      'Content-Type': 'application/json; charset=UTF-8',

    },

    body: jsonEncode({

      'title': title,

    }),

  );

  

  if (response.statusCode == 200) {

    return Album.fromJson(json.decode(response.body));

  } else {

    throw Exception('Failed to update the album!');

  }

}

  

// the album class

class Album {

  final int id;

  final String title;

  

  Album({this.id, this.title});

  

  factory Album.fromJson(Map json) {

    return Album(

      id: json['id'],

      title: json['title'],

    );

  }

}

  

void main() {

  runApp(MyApp());

}

  

class MyApp extends StatefulWidget {

  MyApp({Key key}) : super(key: key);

  

  @override

  _MyAppState createState() {

    return _MyAppState();

  }

}

  

class _MyAppState extends State {

  final TextEditingController _controller = TextEditingController();

  Future _futureAlbum;

  

  @override

  void initState() {

    super.initState();

    _futureAlbum = getAlbum();

  }

  

  @override

  Widget build(BuildContext context) {

    return MaterialApp(

      title: 'Update Data',

      theme: ThemeData(

        primarySwatch: Colors.blue,

      ),

      home: Scaffold(

        appBar: AppBar(

          title: Text('GeeksForGeeks'),

          backgroundColor: Colors.green,

        ),

        body: Container(

          alignment: Alignment.center,

          padding: const EdgeInsets.all(8.0),

          child: FutureBuilder(

            future: _futureAlbum,

            builder: (context, snapshot) {

              if (snapshot.connectionState == ConnectionState.done) {

                if (snapshot.hasData) {

                  return Column(

                    mainAxisAlignment: MainAxisAlignment.center,

                    children: [

                      Text(snapshot.data.title),

                      TextField(

                        controller: _controller,

                        decoration: InputDecoration(hintText: 'Enter Title'),

                      ),

                      RaisedButton(

                        child: Text('Update Data'),

                        onPressed: () {

                          setState(() {

                            _futureAlbum = updateAlbum(_controller.text);

                          });

                        },

                      ),

                    ],

                  );

                } else if (snapshot.hasError) {

                  return Text("${snapshot.error}");

                }

              }

              return CircularProgressIndicator();

            },

          ),

        ),

      ),

    );

  }

}

Output:

0 comments

Warning: PHP Startup: Unable to load dynamic library 'imagick.so' (tried: /usr/local/lib/php/extensions/no-debug-non-zts-20210902/imagick.so (/usr/local/lib/php/extensions/no-debug-non-zts-20210902/imagick.so: cannot open shared object file: No such file or directory), /usr/local/lib/php/extensions/no-debug-non-zts-20210902/imagick.so.so (/usr/local/lib/php/extensions/no-debug-non-zts-20210902/imagick.so.so: cannot open shared object file: No such file or directory)) in Unknown on line 0