Flutter – WebSockets

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

filter_none

edit
close

play_arrow

link
brightness_4
code

StreamBuilder(
  stream: widget.channel.stream,
  builder: (context, snapshot) {
    return Text(snapshot.hasData ? '${snapshot.data}' : '');
  },
);

chevron_right


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

filter_none

edit
close

play_arrow

link
brightness_4
code

import 'dart:async';
import 'dart:convert';
  
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
  
Future<Album> fetchAlbum() async {
  final response =
  
  if (response.statusCode == 200) {
    return Album.fromJson(json.decode(response.body));
  } else {
    throw Exception('Loading album failed!');
  }
}
  
Future<Album> updateAlbum(String title) async {
  final http.Response response = await http.put(
    headers: <String, String>{
      'Content-Type': 'application/json; charset=UTF-8',
    },
    body: jsonEncode(<String, String>{
      '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<String, dynamic> 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<MyApp> {
  final TextEditingController _controller = TextEditingController();
  Future<Album> _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<Album>(
            future: _futureAlbum,
            builder: (context, snapshot) {
              if (snapshot.connectionState == ConnectionState.done) {
                if (snapshot.hasData) {
                  return Column(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: <Widget>[
                      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();
            },
          ),
        ),
      ),
    );
  }
}

chevron_right


Output:




My Personal Notes arrow_drop_up


If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.


Article Tags :

1


Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.