{"id":15698077,"url":"https://github.com/mokira3d48/python-socket.io-django","last_synced_at":"2025-05-09T01:08:30.530Z","repository":{"id":169563557,"uuid":"392776525","full_name":"mokira3d48/python-socket.io-django","owner":"mokira3d48","description":"Raw socket.io integration in a django server.","archived":false,"fork":false,"pushed_at":"2022-12-20T23:59:36.000Z","size":93,"stargazers_count":8,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-05-09T01:08:24.162Z","etag":null,"topics":["asyncio","django","eventlet","gevent","long-polling","low-latency","python","socket-io","socketio","web-server","websocket"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mokira3d48.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-08-04T17:33:31.000Z","updated_at":"2024-07-21T08:39:00.000Z","dependencies_parsed_at":null,"dependency_job_id":"0f473b7a-7bcd-407d-bad4-975336549006","html_url":"https://github.com/mokira3d48/python-socket.io-django","commit_stats":null,"previous_names":["mokira3d48/python-socket.io-django"],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mokira3d48%2Fpython-socket.io-django","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mokira3d48%2Fpython-socket.io-django/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mokira3d48%2Fpython-socket.io-django/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mokira3d48%2Fpython-socket.io-django/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mokira3d48","download_url":"https://codeload.github.com/mokira3d48/python-socket.io-django/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253171258,"owners_count":21865293,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["asyncio","django","eventlet","gevent","long-polling","low-latency","python","socket-io","socketio","web-server","websocket"],"created_at":"2024-10-03T19:23:08.738Z","updated_at":"2025-05-09T01:08:30.491Z","avatar_url":"https://github.com/mokira3d48.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# python-socket.io-django\n![](https://img.shields.io/badge/Python-3.8.10-blue)\n![](https://img.shields.io/badge/Django-3.2.6-%2344B78B)\n![](https://img.shields.io/badge/socket.io-5.4.0-%23fff)\n\nRaw socket.io integration in a django server.\n\n\n- French version is [here](https://github.com/mokira3d48/python-socket.io-django/tree/master/fr)\n\n\u003cbr/\u003e\n\n\n## Prérequis\n\nVous devez installer `python version 3.8.10 ou plus` sur votre machine.\nSous Ubuntu :\n\n```\nsudo apt install python3\n```\nSous certaines distributions linux,\n```\nsudo apt install python\n```\n\n\u003cbr/\u003e\n\nPS : Si vous verifiez la version et qu'elle n'est la bonne `3.8.10 ou plus`, alors cherchez comment installer ou mettre\nà jour ce qui a été installé.\n\n\u003cbr/\u003e\n\nEnsuite, installer le gestionnaire de dépendance `pip3` pour python3.\nSous Ubuntu :\n\n```\nsudo apt install python3-pip\n```\n\n\n\u003cbr/\u003e\n\n\n## Version de python\nExécutez la ligne de commande suivante pour vérifier votre version de `python`.\n```\npython --version\n```\nPS : Pour ceux qui sont sur certain système `Linux` notamment `Ubuntu`, exécuter plutôt la ligne de commande suivante :\n```\npython3 --version\n```\n \nChez moi en ce moment, ma version de python est `3.8.10`.\n```\nPython 3.8.10\n```\nJe vous recommande d'avoir cette version ou une version supérieur à celle-ci.\n\n\u003cbr/\u003e\n\n\n## Configuration d'un environnement virtuel\n\nAvant d'installer les modules, il faut créer un environnement virtuel. C'est dans ce dernier, qu'on va \ninstaller les différents modules du serveur.\n\n\n\n### Installation de virtualenv\n\nOn va utiliser `virtualenv` pour créer un environnement virtuel.\n\n```\nsudo pip3 install virtualenv\n```\n\nEnsuite, dans le dossier du projet, créer un environement virtuel en tapant la commande suivante :\n\n```\npython3 -m venv env\n```\n\n\n### Activation de l'environnement\nEnfin, on active l'environement virtuel\n\n```\nsource env/bin/activate\n```\n\nSi tous va bien, on peut passer à l'installation des modules.\n\n\u003cbr/\u003e\n\n\n## Installation des modules\nVoici tous les modules dont on a besoin pour monter notre serveur socket.\n\nContenu du fichier `requirements.txt` :\n\n```\nasgiref==3.4.1\nbidict==0.21.2\nDjango==3.2.6\ndnspython==1.16.0\nenum-compat==0.0.3\neventlet==0.30.0\ngevent==21.1.2\ngevent-websocket==0.10.1\ngreenlet==0.4.17\npython-engineio==4.2.1\npython-socketio==5.4.0\npytz==2021.1\nsix==1.10.0\nsqlparse==0.4.1\nzope.event==4.5.0\nzope.interface==5.4.0\n\n```\nUtiliser la commande suivante pour installer tous les modules contenus dans le fichier.\nVous pouvez aussi les installer un a un afin d'avoir leur dernière version.\n\n```\npip install -r requirements.txt\n```\n\n\u003cbr/\u003e\n\n## Creation d'un projet Django\nOn va maintenant créer un projet Django nommé `django_socketio` par exemple.\n\n```\ndjango-admin startproject django_socketio\n```\n\nIl faut créer ensuite une application. C'est dans cette dernière qu'on va implémenter un exemple de programme de chat pour tester notre serveur de `socket.io`.\n\n```\ndjango-admin startapp socketio_app\n```\n\n\u003cbr/\u003e\n\n## Configuration du projet\nOn va placer les boûts de code qu'il faut dans certains fichiers de django.\n\n\n### Configuration de l'URL\n1. Dans le fichier `django_socketio/urls.py`, insérer la ligne suivante :\n\n```python\nfrom django.conf.urls import url, include\n\n# ...\n```\n\nensuite,\n\n```python\n# ...\n\nurlpatterns = [\n    url(r'', include('socketio_app.urls')),\n    path('admin/', admin.site.urls),\n]\n```\n\n\u003cbr/\u003e\n\n2. Dans le dossier `django_socketio/socketio_app/`, créez le fichier `urls.py` et insérer s'y\nle code suivant :\n\n```python\nfrom django.conf.urls import url\n\nfrom . import views\n\nurlpatterns = [\n    url(r'', views.index, name='index'),\n];\n\n```\n\n\n### Configuration du serveur en socket.io\nOn va maintenant mettre en place les fonctionnalités du serveur de socket.io.\n\n1. Dans le fichier `django_socketio/socketio_app/views.py` insérer les lignes de code suivantes :\n\n```python\nimport socketio\n\n# mode d'asynchronisation\nasync_mode = 'gevent';\n\n# definition du serveur de socket.io\nsio = socketio.Server(async_mode=async_mode);\n\n\n```\n\n\u003cbr/\u003e\n\n![Stratégie de déploiement](https://www.botreetechnologies.com/blog/wp-content/uploads/2020/12/deployment-strategy.jpg, \"Stratégie de déploiement\")\n\n- Le déploiement est délicat, car les sockets ne sont pas basés sur le protocole HTTP. Le serveur d'applications alloue généralement un processus ou un fil distinct pour chaque demande. Par conséquent, nous devons utiliser `Gevent`, qui agit comme une boucle d'événements et chaque fois qu'il y a une demande de connexion, il génère un nouveau thread et attribue la connexion à ce thread.\n\n- Nous avons décidé de séparer l'application socket de l'application normale, car la prise en charge à la fois de la fonction Django normale et de l'application socket dans une seule `application Django` rendait la gestion des réponses aux requêtes lente.\n\n- Le déplacement du code socketio vers une autre application a également facilité la maintenance du code.\n\nPar [ici](https://www.botreetechnologies.com/blog/django-websocket-with-socketio/) pour en savoir plus.\n\n\u003cbr/\u003e\n\n\n2. Remplacez les lignes de code du fichier `django_socketio/wsgi.py` par les suivantes :\n\n```python\nimport os\nimport socketio\n\nfrom django.core.wsgi import get_wsgi_application\nfrom socketio_app.views import sio\n\nos.environ.setdefault('DJANGO_SETTINGS_MODULE', 'django_socketio.settings');\n\ndjango_app  = get_wsgi_application();\napplication = socketio.WSGIApp(sio, django_app);\n\n####################################################################################\n\nfrom gevent import pywsgi\nfrom geventwebsocket.handler import WebSocketHandler\n\nserver = pywsgi.WSGIServer((\"\", 8000), application, handler_class=WebSocketHandler);\nserver.serve_forever();\n\n```\n \n\u003cbr/\u003e\n\n## Implémentation des exemples de fonctionnalités avec socket.io\nOn va mettre en place le programme serveur et un programme client.\n\n### Programme serveur\n\nOn va juste essayer d'implémenter un programme de chat. Remplacez donc tous le code contenu dans le fichier `django_socketio/socketio_app/views.py` par les lignes de code suivantes :\n\n```python\n# définissez async_mode sur 'threading', 'eventlet', 'gevent' ou 'gevent_uwsgi' sur\n# forcer un autre mode, le meilleur mode est sélectionné automatiquement parmi ce qui est\n# installée\nsync_mode = 'gevent';\n\nimport os\n\nfrom django.http import HttpResponse\nimport socketio\n\nbasedir = os.path.dirname(os.path.realpath(__file__));\nsio     = socketio.Server(async_mode=async_mode);\n\n# thread = None\nusers = {};\n\ndef index(request):\n    \"\"\" \n        Programme qui permet de renvoiyer la page web `index`\n    \"\"\"\n\n    # global thread;\n\n#    if thread is None:\n#        thread = sio.start_background_task(background_thread);\n\n    return HttpResponse(open(os.path.join(basedir, 'static/index.html')));\n\n\n# def background_thread():\n#     \"\"\" Exemple de programme d'execution de programme d'arriere plan \"\"\"\n\n#     count = 0;\n\n#     while True:\n#         sio.sleep(10);\n#         count += 1;\n#         sio.emit('my_response', {'data': 'Server generated event'}, namespace='/test');\n\n@sio.event\ndef set_username(sid, message):\n    \"\"\" Programme de modification du nom d'utilisateur \"\"\"\n    users[sid] = message['data'];\n\n    # on notifit que le username a ete correctement notifie\n    sio.emit('my_response', {'data': f\"Username is set to {users[sid]} !\"}, to=sid);\n\n\n\n@sio.event\ndef my_event(sid, message):\n    # Programme qui permet d'envoyer le message a moi meme\n    sio.emit('my_response', {'data': message['data']}, room=sid);\n\n\n\n@sio.event\ndef my_broadcast_event(sid, message):\n    # Programme qui permet d'envoyer le message a tous le monde\n    sio.emit('my_response', {'data': f\"[{users[sid]}] {message['data']}\"});\n\n\n\n@sio.event\ndef join(sid, message):\n    \"\"\" Programme de creation et d'adesion de canale \"\"\"\n\n    # on cree le canale et on se join a ce canal\n    sio.enter_room(sid, message['room']);\n\n    # sio.emit('my_response', {'data': 'Entered room: ' + message['room']}, room=sid);\n\n    # on emet a tous ceux qui sont dans le canal qu'on de \n    # rejoindre le canal\n    sio.emit('my_response', {'data': 'Entered room: ' + message['room']}, to=message['room']);\n\n\n@sio.event\ndef leave(sid, message):\n    \"\"\" Programme de deconnection d'un canal \"\"\"\n\n    # on se deconnecte du canal\n    sio.leave_room(sid, message['room']);\n\n    # on informe tous ceux qui sont dans le canal, que celui-ci \n    # a quitte le canal\n    sio.emit('my_response', {'data': users[sid] + ' left room: ' + message['room']}, room=message['room']);\n\n\n@sio.event\ndef close_room(sid, message):\n    \"\"\" Programme de fermeture d'un canal \"\"\"\n\n    # on ferme le canal\n    sio.close_room(message['room']);\n    sio.emit('my_response', {'data': 'Room ' + message['room'] + ' is closing.'}, room=message['room']);\n\n\n@sio.event\ndef my_room_event(sid, message):\n    \"\"\" Programme qui permet d'envoyer un message a tous les membres du canal \"\"\"\n    sio.emit('my_response', {'data': f\"[{users[sid]}] {message['data']}\"}, room=message['room']);\n\n\n@sio.event\ndef disconnect_request(sid):\n    \"\"\" Programme qui declanche la deconnection de l'utilisateur \"\"\"\n    sio.disconnect(sid);\n\n\n@sio.event\ndef connect(sid, environ):\n    \"\"\" Programme de connexion \n        Au cour de la connexion, on enregistre tous les utilisateurs \n        connectes\n    \"\"\"\n\n    print(f\"{sid}\\t connected\");\n\n    # on ajoute le nouveau a la liste\n    users[sid] = None;\n\n    # on lui notifie qu'il s'est bien connecte\n    sio.emit('my_response', {'data': 'Connected', 'count': len(users)}, room=sid);\n\n    # on notifie a tous le monde le nombre de personnes actuellement connectes\n    sio.emit('my_response', {'data': f'{len(users)} connected now!', 'count': len(users)});\n\n\n@sio.event\ndef disconnect(sid):\n    \"\"\" Programme de deconnexion\n        Lors de la deconnexion, on supprime l'utilisateur de la liste des\n        connectes\n    \"\"\"\n\n    print(f\"{sid}\\t {users[sid]} disconnected\");\n\n    # on notifie a tous le monde le nombre de personnes actuellement connectes\n    sio.emit('my_response', {'data': f\"{users[sid]} is disconnected\", 'count': len(users)});\n\n    # on le supprime de la liste \n    del users[sid];\n\n    # on notifie a tous le monde le nombre de personnes actuellement connectes\n    sio.emit('my_response', {'data': f'{len(users)} connected', 'count': len(users)});\n\n\n```\n\n### Programme client\nEn effet, il s'agit de mettre en place une interface WEB. \u003cbr/\u003e\nDans le dossier `django_socketio/socketio_app/`, créez un dossier nommé `static`, ensuite, dans ce dernier, créer un fichier nommé `index.html`. Dans ce fichier, insérez les lignes de code suivantes :\n\n```html\n\u003c!DOCTYPE HTML\u003e\n\u003chtml\u003e\n    \u003chead\u003e\n        \u003ctitle\u003eDjango + SocketIO Test\u003c/title\u003e\n        \u003cscript type=\"text/javascript\" src=\"//code.jquery.com/jquery-3.2.1.slim.min.js\"\u003e\u003c/script\u003e\n        \u003cscript type=\"text/javascript\" src=\"//cdnjs.cloudflare.com/ajax/libs/socket.io/3.0.3/socket.io.min.js\"\u003e\u003c/script\u003e\n        \u003cscript type=\"text/javascript\" charset=\"utf-8\"\u003e\n            $(document).ready(function(){\n                var socket = io.connect();\n\n                socket.on('connect', function() {\n                    socket.emit('my_event', {data: 'I\\'m connected!'});\n                });\n                socket.on('disconnect', function() {\n                    $('#log').append('\u003cbr\u003eDisconnected');\n                });\n                socket.on('my_response', function(msg) {\n                    $('#log').append('\u003cbr\u003eReceived: ' + msg.data);\n                });\n\n                // event handler for server sent data\n                // the data is displayed in the \"Received\" section of the page\n                // handlers for the different forms in the page\n                // these send data to the server in a variety of ways\n                $('form#username').submit(function(event) {\n                    socket.emit('set_username', {data: $('#name_data').val()});\n                    return false;\n                });\n                $('form#emit').submit(function(event) {\n                    socket.emit('my_event', {data: $('#emit_data').val()});\n                    return false;\n                });\n                $('form#broadcast').submit(function(event) {\n                    socket.emit('my_broadcast_event', {data: $('#broadcast_data').val()});\n                    return false;\n                });\n                $('form#join').submit(function(event) {\n                    socket.emit('join', {room: $('#join_room').val()});\n                    return false;\n                });\n                $('form#leave').submit(function(event) {\n                    socket.emit('leave', {room: $('#leave_room').val()});\n                    return false;\n                });\n                $('form#send_room').submit(function(event) {\n                    socket.emit('my_room_event', {room: $('#room_name').val(), data: $('#room_data').val()});\n                    return false;\n                });\n                $('form#close').submit(function(event) {\n                    socket.emit('close_room', {room: $('#close_room').val()});\n                    return false;\n                });\n                $('form#disconnect').submit(function(event) {\n                    socket.emit('disconnect_request');\n                    return false;\n                });\n            });\n        \u003c/script\u003e\n    \u003c/head\u003e\n    \u003cbody\u003e\n        \u003ch1\u003eDjango + SocketIO Test\u003c/h1\u003e\n        \u003ch2\u003eSend:\u003c/h2\u003e\n        \u003cform id=\"username\" method=\"POST\" action='#'\u003e\n            \u003cinput type=\"text\" name=\"username\" id=\"name_data\" placeholder=\"Username\"\u003e\n            \u003cinput type=\"submit\" value=\"Set name\"\u003e\n        \u003c/form\u003e\n        \u003cform id=\"emit\" method=\"POST\" action='#'\u003e\n            \u003cinput type=\"text\" name=\"emit_data\" id=\"emit_data\" placeholder=\"Message\"\u003e\n            \u003cinput type=\"submit\" value=\"Echo\"\u003e\n        \u003c/form\u003e\n        \u003cform id=\"broadcast\" method=\"POST\" action='#'\u003e\n            \u003cinput type=\"text\" name=\"broadcast_data\" id=\"broadcast_data\" placeholder=\"Message\"\u003e\n            \u003cinput type=\"submit\" value=\"Broadcast\"\u003e\n        \u003c/form\u003e\n        \u003cform id=\"join\" method=\"POST\" action='#'\u003e\n            \u003cinput type=\"text\" name=\"join_room\" id=\"join_room\" placeholder=\"Room Name\"\u003e\n            \u003cinput type=\"submit\" value=\"Join Room\"\u003e\n        \u003c/form\u003e\n        \u003cform id=\"leave\" method=\"POST\" action='#'\u003e\n            \u003cinput type=\"text\" name=\"leave_room\" id=\"leave_room\" placeholder=\"Room Name\"\u003e\n            \u003cinput type=\"submit\" value=\"Leave Room\"\u003e\n        \u003c/form\u003e\n        \u003cform id=\"send_room\" method=\"POST\" action='#'\u003e\n            \u003cinput type=\"text\" name=\"room_name\" id=\"room_name\" placeholder=\"Room Name\"\u003e\n            \u003cinput type=\"text\" name=\"room_data\" id=\"room_data\" placeholder=\"Message\"\u003e\n            \u003cinput type=\"submit\" value=\"Send to Room\"\u003e\n        \u003c/form\u003e\n        \u003cform id=\"close\" method=\"POST\" action=\"#\"\u003e\n            \u003cinput type=\"text\" name=\"close_room\" id=\"close_room\" placeholder=\"Room Name\"\u003e\n            \u003cinput type=\"submit\" value=\"Close Room\"\u003e\n        \u003c/form\u003e\n        \u003cform id=\"disconnect\" method=\"POST\" action=\"#\"\u003e\n            \u003cinput type=\"submit\" value=\"Disconnect\"\u003e\n        \u003c/form\u003e\n        \u003ch2\u003eReceive:\u003c/h2\u003e\n        \u003cdiv\u003e\u003cp id=\"log\"\u003e\u003c/p\u003e\u003c/div\u003e\n    \u003c/body\u003e\n\u003c/html\u003e\n\n```\n\n\u003cbr/\u003e\n\n## Démarrage du serveur\nN'oublier pas de sauvegarder tous les fichiers sources. Il est temps de tester notre programme.\nOn doit d'abord faire un migration dans une base de données avant de démarrer le serveur.\nPour faire la migration, tappez la commande suivante :\n\n```\n./manage.py migrate\n```\n\nOn peut maintenant démarrer le serveur avec la commande suivante :\n\n```\n./manage.py runserver\n```\n\nSi tout va bien, vous verrez le message suivant affichez dans votre terminal.\n\n```\nWatching for file changes with StatReloader\nPerforming system checks...\n\nSystem check identified no issues (0 silenced).\nAugust 30, 2021 - 01:55:05\nDjango version 3.2.6, using settings 'django_socketio.settings'\nStarting development server at http://127.0.0.1:8000/\nQuit the server with CONTROL-C.\n```\n\n\u003cbr/\u003e\n\n## Test\nVoici le lien pour accéder à l'interface web : [http://127.0.0.1:8000/](http://127.0.0.1:8000/).\nPour que d'autre ordinateur puisse accéder à votre application, il faut qu'ils soient dans le même réseau que votre ordinateur. Ensuite, ils doivent utiliser votre adresse IP (souvent sous la forme `192.168.xxx.xxx`). Pour connaitre votre adresse IP :\n\n- sous linux :\n\n```\nsudo ifconfig\n```\n\n- sous windows :\n\n```\nipconfig\n```\nEnsuite rendez-vous dans le fichier `django_socketio/settings.py` pour permettre l'accès au serveur via cet adresse IP. Si par exemple mon adresse IP est `192.168.100.31`, alors vous devez modifier la ligne de code suivante dans le fichier `django_socketio/settings.py`\n\n```python\n# ...\n\nALLOWED_HOSTS = ['192.168.100.31'];\n\n# La ligne ci-dessus permettra au autre ordinateur qui sont sur le même réseau que moi \n# de pouvoir accéder à mon serveur socket.io via le lien http://192.168.100.31:8000/\n\n# ...\n```\n\n\n\u003cbr/\u003e\n\n## Système d'exploitation\n\n```\nKernel: 5.8.0-59-generic x86_64 bits: 64 compiler: N/A Desktop: Gnome 3.36.9 \nDistro: Ubuntu 20.04.2 LTS (Focal Fossa)\n```\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmokira3d48%2Fpython-socket.io-django","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmokira3d48%2Fpython-socket.io-django","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmokira3d48%2Fpython-socket.io-django/lists"}