Open In App

Flutter – WebSockets

Improve
Improve
Like Article
Like
Save
Share
Report

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<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();
            },
          ),
        ),
      ),
    );
  }
}


Output:



Last Updated : 10 Sep, 2020
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads