How you can use WebSockets with Flutter
Tags: flutter, tutorial, mobile, android
Published: 2021-10-12 19:43:41


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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/enqzo6avfi1bykppcadf.png)
 
 
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?](https://www.pcmag.com/encyclopedia/term/clientserver#:~:text=An%20architecture%20in%20which%20the,WAN%29%20such%20as%20the%20Internet.)

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](https://ably.com/topic/socketio) if you haven't already._
## How to connect to a WebSocket server with Flutter 
### [`web_socket_channel`](https://pub.dev/packages/web_socket_channel) package
We will use this package to acquire the tools we need to connect to a WebSocket server. 
![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9y4379cj5cgz0xqr1h7w.png)
 
- The `web_socket_channel` basically works with the ***StreamChannel*** class, which is an abstract class representing a two-way communication channel (as in the case for WebSockets)
- Each `StreamChannel` exposes a `Stream` for **receiving data**. A `Stream`  is like a pipe, you put a value on the one end and if there’s a listener on the other end that listener will receive that value.
- It also exposes `StreamSink` used to push messages to the server.
 


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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a36fwmllw3dfmptr35ae.png)
 

- We'd have a textfield in our app where the user could type a message. The data that we input would be displayed on the screen after pressing a button.

- The data displayed comes from the server response, which is an echo server in this case, meaning it sends back what it receives. These servers are used to determine whether or not a connection to a server is successful. Here we would be using them to maintain simplicity for this example. 

Here is the boiler plate we will be using:
{% gist https://gist.github.com/vibalijoshi/5fcdf785242d0222d9ba0026ed6ef42c %}

### How to connect to server

First let us connect to a WebSocket server. As discussed above we will be using an echo webSocket server. 
```dart
WebSocketChannel channel = IOWebSocketChannel.connect("wss://ws.ifelse.io/");
```
- `WebSocketChannel`: A *StreamChannel* (class representing a two-way communication) that communicates over a WebSocket.
- `IOWebSocketChannel`: A [WebSocketChannel](https://docs-flutter-io.firebaseapp.com/flutter/package-web_socket_channel_web_socket_channel/WebSocketChannel-class.html) that communicates using a `dart:io`  [WebSocket](https://docs-flutter-io.firebaseapp.com/flutter/dart-io/WebSocket-class.html).
- `IOWebSocketChannel.connect`: Creates a new WebSocket connection and connects to  `url`  using  [WebSocket.connect](https://api.dart.dev/stable/2.14.2/dart-io/WebSocket/connect.html)  and returns a channel that can be used to communicate over the resulting socket. 
- Here `wss://ws.ifelse.io/` is an echo WebSocket server. Please note that the mostly used echo server `ws://echo.websocket.org` is no longer in service. 

{% gist https://gist.github.com/vibalijoshi/faf62d551190a46d67bad7ea8f427aa5 %}

### How to listen to the server
![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gx4kcdw8mkh3gtk6jq09.png)
- Now that we’ve established a connection, let us listen to messages from the server.
- After sending a message to the test server, it sends the same message back (echo). 
- We will use a  [`StreamBuilder`](https://api.flutter.dev/flutter/widgets/StreamBuilder-class.html)  widget to listen for new messages, and a  `Text` widget to display them.
- A StreamBuilder:
  1. Can listen to exposed streams.
  2. Return widgets
  3. Catch snapshots of got stream information.
 
```dart
StreamBuilder(  
  stream: widget.channel.stream,  
  builder: (context, snapshot) {  
    return Padding(  
      padding: const EdgeInsets.all(20.0),  
  child: Text(snapshot.hasData ? '${snapshot.data}' : ''),  
  );  
  },  
)
```
>  Watch [this](https://youtu.be/MkKEWHfy99Y) video to get a better idea about StreamBuilder:   
>  

### How to Send data to the server
![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yq8ec511lodh34sfenkl.png)
 

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

```dart
void sendData() {  
  if (_controller.text.isNotEmpty) {  
    widget.channel.sink.add(_controller.text);  
  }  
}
```
- `channel.sink.add()`: for sending values to the other endpoint of the stream (i.e the server) using the sink property of the WebSocketChannel. 
- To make sure we are printing not empty data we add a 

### How to close the connection?
Using the close method we can disconnect from the server. 
```dart
void dispose() {  
  widget.channel.sink.close();  
 super.dispose();  
}
```

### Final Code


{% gist https://gist.github.com/vibalijoshi/87c5e6c310b0e6e0a54c2409bee751cb %}

If you successfully connected to the server then you would see this on the emulator. 
![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u8q2ko45qfno56jsjbui.png)

This is how your app should look at the end:
![Animation](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hzcjif83d03h38382sjw.gif)
 
### 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: 
- Web-based games
- Chatting Applications