Flutter & Python Web-Socket Ft. Socket-IO (Part 1)
Tags: flutter, python, mysql, socketio
Published: 2022-07-27 07:59:32

Welcome back Guys, We are going to build real time chat application using Web Socket,Client application in Flutter and Server application in Python using Flask and MySQL as Database.

**Hold Your Devices, We are not going to rush in this and this is going to be in parts.**

> ## What is Web Socket ?

WebSocket is a communication protocol used in client-server communication. 

WebSocket is a bidirectional communication protocol that can send the data from the client to the server or from the server to the client by reusing the established connection channel. The connection is kept alive until terminated by either the client or the server.

[Read more](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API)

> ## Why we are going to Use WebSocket not Rest APIs?

As we are going to create real time application that's mean any user can send message any time if you use REST API, we need to request from server to get new message but how can we know that any user has sent message or not? By using Periodic Request from client to server? But is this is the best way?

No this is not best way that's why we are going to use WebSocket in which Both Server and Client will be connected and both of them can request to each other.

Look below for getting clear picture,difference between WebSocket and HTTP Request.


![WEBSOCKET](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ul5u9ah667310s2t038q.gif)


> Prerequisite

- Python IDE(Recommended [PyCharm](https://www.jetbrains.com/pycharm/)) 
- [MySQL](https://dev.mysql.com/downloads/mysql/) Server
- SocketIO Client Extension( [Chrome](https://chrome.google.com/webstore/detail/firecamp-a-multi-protocol/eajaahbjpnhghjcdaclbkeamlkepinbl) & [Firefox](https://addons.mozilla.org/en-US/firefox/addon/socketio-client/))
- [Flutter and Dart SDK](https://docs.flutter.dev/get-started/install)

> Lets Start

- Create a new python project or new file **main.py**.
- Install following library using PIP

```
pip install Flask-MySQL
pip install Flask-SocketIO
pip install cryptography
```
- import all the required packages

```
from flask import Flask, session, jsonify
from flask_socketio import SocketIO, join_room, leave_room, emit
from flaskext.mysql import MySQL

import datetime

```

-  Create a simple Socket IO Flask 

```
# Flask App Config
app: Flask = Flask(__name__)

app.config['SECRET_KEY'] = 'secret'
app.config['SESSION_TYPE'] = 'filesystem'

# CORS_ALLOWED_ORIGINS is the list of origins authorized to make requests.
socketio = SocketIO(app, cors_allowed_origins='*')


# Home Page
@app.route('/', methods=['GET', 'POST'])
def index():
    return jsonify({'data': "Web Socket Example"})


if __name__ == '__main__':
    # Run Flask-SocketIO App
    socketio.run(app, debug=True)

```

![OUTPUT1](https://imgur.com/hWIznt0.png)
 

> Before going forward lets understand what is socket.emit(),socket.on() and Room in Socket IO?

- **[Room](https://socket.io/docs/v3/rooms/)** : as Name suggested Room is place(channel) in server where different clients can join and leave and also from there message can be broadcast to all the clients in same room.

Note: Only those client will be receiving who are in same room not from different room.

- **[Socket.emit() Event](https://socket.io/docs/v4/server-api/#socketemiteventname-args)** : Emits an event to the socket identified by the string name. Any other parameters can be included. All serializable data structures are supported, including Buffer.
- **[Socket.on() Event](https://socket.io/docs/v4/server-api/#socketemiteventname-args)** : Socket.on() is an event handler that take information from client and process.
 
**Server**

```
io.on("connection", (socket) => {
  socket.emit("hello", "world", (response) => {
    console.log(response); // "got it"
  });
});
```

**Client**

```
socket.on("hello", (arg, callback) => {
  console.log(arg); // "world"
  callback("got it");
});
```

- We are going to following logic for designing backed and frontend.


![INFO2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0xnnje9xzw3l5tklpivl.jpg)

Note: Database will be introduce in upcoming parts so for being now we are not going to persistent message.

- Add following lines of codes below def index() function.

```
@socketio.on('join', namespace='/chat')
def join(message):
    # we need roomId and Username for joining the room 
    room = message['roomId']
    username = message['username']
    # join room 
    join_room(room)
    # Emit message or notifier to other user of same room 
    emit('message', {"msg": {str(username) + 'has joined the room.'}}, room=room)


@socketio.on('text', namespace='/chat')
def text(message):
    room = message['room']
    username = message['username']
    msg = message['msg']
    emit('message', {"msg": {str(username) + ' : ' + str(msg)}}, room=room)


@socketio.on('left', namespace='/chat')
def left(message):
    room = message['room']
    username = message['username']
    # leaving the room
    leave_room(room=room)
    emit('message', {"msg": {str(username) + 'has left the room.'}}, room=room)
```
- Now run the app and open Socket IO Client.
Note URL for connecting socket IO will be(localhost)
"http://localhost:5000/chat"
where **chat** is namespace.

 
- Lets test, join first and sent following data:
  

```
{
"roomId":"test1223",
"username":"smk"
}
```
![output2](https://imgur.com/vDUbwJj.png)
- Now sent message in same room with following JSON data:

```
{
"room":"test1223",
"username":"smk",
"msg":"hello"
}
```
Note: Do not forgot to change on event name 'join' to 'text'.

![output3](https://imgur.com/kKymxv1.png)

- Lets try to leave the room by sending request to server and following data:

```
{
"room":"test1223",
"username":"smk",
}
```
![OUTPUT4](https://imgur.com/LSLUG4n.png)



Hurray we are done........

In Next part we are going to setup MySQL Database to web socket server and persist the message.

Stay Tuned....

- [**Source Code**](https://github.com/Djsmk123/web_socket_example_backend)

> Follow me:

- [GitHub](https://github.com//djsmk123)

- [LinkedIn](https://www.linkedin.com/in/md-mobin-bb928820b)

- [Twitter](https://twitter.com/smk_winner)