WebSocket is a communications protocol, providing two-way interactive communication sessions between a client and the server. With WebSocket, you can send and receive event-driven messages. In this tutorial, we're going to create a socket server using SocketIO to build a simple chat application. SocketIO is a standard library implemented in multiple languages such as Python, JavaScript, Java and etc, which helps us to do that in an easy way. Actually, SocketIO is NOT a WebSocket implementation. Although it indeed uses WebSocket as transport when possible. You can consider the SocketIO as a slight wrapper around the WebSocket API. So, let's start:
The first step to create a chat application is to create a socket server. First of all, get the simple chat app repository using the command below:
git clone https://github.com/aryan-arabshahi/code-with-coffee-samples.git
cd ./code-with-coffee-samples/simple_chat
If you want to run the application to see how it looks, use:
pip install .
simple-chat
Note that if you are running it on another machine (VM or a remote server), you must make a build of the react project with the remote IP which is set in the config.json file.
let's have a look into the project structure:
simple_chat
│
├── MANIFEST.in
├── README
├── requirements.txt
├── setup.py
│
└── simple_chat
│
├── app.py
├── socketio.py
├── enums.py
├── globals.py
├── __init__.py
│
├── cli
│ ├── __init__.py
│ └── main.py
│
└── react_app
└── build
There is a pre-build react application that is serving by Flask. To do that, we have the MANIFEST.in file that defines the included directories:
recursive-include simple_chat/react_app/build *
The "main.py" is the entry point of the project which is using the “app.py” to start the socket server:
from simple_chat.app import ChatApp
def main():
chat_app = ChatApp()
chat_app.start()
if __name__ == '__main__':
main()
The flask_app variable is defined in the “globals.py” and the react build folder has been used for the static and the template paths:
from flask import Flask
from flask_cors import CORS
flask_app = Flask(__name__, static_folder='react_app/build/static', template_folder='react_app/build')
CORS(flask_app)
In this way, The Flask app can serve the react project too, but before that, we must define a route to return the index.html which is in the app.py:
from flask import render_template
from .globals import flask_app
from .socketio import socketio
@flask_app.route('/')
def index():
return render_template('index.html')
class ChatApp:
def start(self) -> None:
"""Run the flask app
"""
socketio.run(
app=flask_app,
host='0.0.0.0',
debug=False,
port=5000
)
And finally, we defined the socket events in the socketio.py:
from flask import request
from flask_socketio import SocketIO
from .globals import flask_app
from .enums import Sender
socketio = SocketIO(flask_app, cors_allowed_origins='*')
@socketio.on('send_message')
def send_message_handler(message: str):
"""Receive the sent messages
Arguments:
message {str}
"""
socketio.emit('receive_message', {
'sender': Sender.OTHERS.value,
'message': f'Server: {message}',
}, to=request.sid)
As you see, there is only the "send_message" event which sends back the client message to himself/herself again.
Now, it turns to create the React application which is talked about in the following link: How to create a chat application in React