Skip to content

Commit

Permalink
Django example
Browse files Browse the repository at this point in the history
  • Loading branch information
miguelgrinberg committed May 31, 2017
1 parent a40e2ab commit 3531b51
Show file tree
Hide file tree
Showing 18 changed files with 440 additions and 5 deletions.
23 changes: 18 additions & 5 deletions examples/wsgi/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ Socket.IO WSGI Examples
=======================

This directory contains example Socket.IO applications that work together with
WSGI frameworks. These examples all use Flask to serve the client application to
the web browser, but they should be easily adapted to use other WSGI compliant
frameworks.
WSGI frameworks. These examples use Flask or Django to serve the client
application to the web browser, but they should be easily adapted to use other
WSGI compliant frameworks.

app.py
------
Expand All @@ -24,6 +24,12 @@ time to the page.
This is an ideal application to measure the performance of the different
asynchronous modes supported by the Socket.IO server.

django_example
--------------

This is a version of the "app.py" application described above, that is based
on the Django web framework.

Running the Examples
--------------------

Expand All @@ -36,13 +42,20 @@ or::

$ python latency.py

or::

$ cd django_example
$ ./manage.py runserver

You can then access the application from your web browser at
``http://localhost:5000``.
``http://localhost:5000`` (``app.py`` and ``latency.py``) or
``http://localhost:8000`` (``django_example``).

Near the top of the ``app.py`` and ``latency.py`` source files there is a
``async_mode`` variable that can be edited to swich to the other asynchornous
modes. Accepted values for ``async_mode`` are ``'threading'``, ``'eventlet'``
and ``'gevent'``.
and ``'gevent'``. For ``django_example``, the async mode can be set in the
``django_example/socketio_app/views.py`` module.

Note 1: when using the ``'eventlet'`` mode, the eventlet package must be
installed in the virtual environment::
Expand Down
Empty file.
121 changes: 121 additions & 0 deletions examples/wsgi/django_example/django_example/settings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
"""
Django settings for django_example project.
Generated by 'django-admin startproject' using Django 1.11.1.
For more information on this file, see
https://docs.djangoproject.com/en/1.11/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.11/ref/settings/
"""

import os

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))


# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.11/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = '+vk#7#92ncb*y)8^$7sd&99%^+xc+t)nmamacbp8^vgjy(&g-9'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = []


# Application definition

INSTALLED_APPS = [
'socketio_app',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]

MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

ROOT_URLCONF = 'django_example.urls'

TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]

WSGI_APPLICATION = 'django_example.wsgi.application'


# Database
# https://docs.djangoproject.com/en/1.11/ref/settings/#databases

DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}


# Password validation
# https://docs.djangoproject.com/en/1.11/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]


# Internationalization
# https://docs.djangoproject.com/en/1.11/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_L10N = True

USE_TZ = True


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.11/howto/static-files/

STATIC_URL = '/static/'
22 changes: 22 additions & 0 deletions examples/wsgi/django_example/django_example/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
"""django_example URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/1.11/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: url(r'^$', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.conf.urls import url, include
2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls'))
"""
from django.conf.urls import url, include
from django.contrib import admin

urlpatterns = [
url(r'', include('socketio_app.urls')),
url(r'^admin/', admin.site.urls),
]
20 changes: 20 additions & 0 deletions examples/wsgi/django_example/django_example/wsgi.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
"""
WSGI config for django_example project.
It exposes the WSGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/1.11/howto/deployment/wsgi/
"""

import os

from django.core.wsgi import get_wsgi_application
from socketio import Middleware

from socketio_app.views import sio

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "django_example.settings")

django_app = get_wsgi_application()
application = Middleware(sio, django_app)
22 changes: 22 additions & 0 deletions examples/wsgi/django_example/manage.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/usr/bin/env python
import os
import sys

if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "django_example.settings")
try:
from django.core.management import execute_from_command_line
except ImportError:
# The above import may fail for some other reason. Ensure that the
# issue is really that Django is missing to avoid masking other
# exceptions on Python 2.
try:
import django
except ImportError:
raise ImportError(
"Couldn't import Django. Are you sure it's installed and "
"available on your PYTHONPATH environment variable? Did you "
"forget to activate a virtual environment?"
)
raise
execute_from_command_line(sys.argv)
Empty file.
3 changes: 3 additions & 0 deletions examples/wsgi/django_example/socketio_app/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from django.contrib import admin

# Register your models here.
5 changes: 5 additions & 0 deletions examples/wsgi/django_example/socketio_app/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from django.apps import AppConfig


class SocketioAppConfig(AppConfig):
name = 'socketio_app'
Empty file.
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
from django.core.management.commands.runserver import Command as RunCommand

from socketio_app.views import sio


class Command(RunCommand):
help = 'Run the Socket.IO server'

def handle(self, *args, **options):
if sio.async_mode == 'threading':
super(Command, self).handle(*args, **options)
elif sio.async_mode == 'eventlet':
# deploy with eventlet
import eventlet
import eventlet.wsgi
from django_example.wsgi import application
eventlet.wsgi.server(eventlet.listen(('', 8000)), application)
elif sio.async_mode == 'gevent':
# deploy with gevent
from gevent import pywsgi
from django_example.wsgi import application
try:
from geventwebsocket.handler import WebSocketHandler
websocket = True
except ImportError:
websocket = False
if websocket:
pywsgi.WSGIServer(
('', 8000), application,
handler_class=WebSocketHandler).serve_forever()
else:
pywsgi.WSGIServer(('', 8000), application).serve_forever()
elif sio.async_mode == 'gevent_uwsgi':
print('Start the application through the uwsgi server. Example:')
print('uwsgi --http :5000 --gevent 1000 --http-websockets '
'--master --wsgi-file django_example/wsgi.py --callable '
'application')
else:
print('Unknown async_mode: ' + sio.async_mode)
Empty file.
3 changes: 3 additions & 0 deletions examples/wsgi/django_example/socketio_app/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from django.db import models

# Create your models here.
91 changes: 91 additions & 0 deletions examples/wsgi/django_example/socketio_app/static/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Django + SocketIO Test</title>
<script type="text/javascript" src="//code.jquery.com/jquery-3.2.1.slim.min.js"></script>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/socket.io/2.0.1/socket.io.slim.js"></script>
<script type="text/javascript" charset="utf-8">
$(document).ready(function(){
namespace = '/test';
var socket = io.connect('http://' + document.domain + ':' + location.port + namespace);

socket.on('connect', function() {
socket.emit('my event', {data: 'I\'m connected!'});
});
socket.on('disconnect', function() {
$('#log').append('<br>Disconnected');
});
socket.on('my response', function(msg) {
$('#log').append('<br>Received: ' + msg.data);
});

// event handler for server sent data
// the data is displayed in the "Received" section of the page
// handlers for the different forms in the page
// these send data to the server in a variety of ways
$('form#emit').submit(function(event) {
socket.emit('my event', {data: $('#emit_data').val()});
return false;
});
$('form#broadcast').submit(function(event) {
socket.emit('my broadcast event', {data: $('#broadcast_data').val()});
return false;
});
$('form#join').submit(function(event) {
socket.emit('join', {room: $('#join_room').val()});
return false;
});
$('form#leave').submit(function(event) {
socket.emit('leave', {room: $('#leave_room').val()});
return false;
});
$('form#send_room').submit(function(event) {
socket.emit('my room event', {room: $('#room_name').val(), data: $('#room_data').val()});
return false;
});
$('form#close').submit(function(event) {
socket.emit('close room', {room: $('#close_room').val()});
return false;
});
$('form#disconnect').submit(function(event) {
socket.emit('disconnect request');
return false;
});
});
</script>
</head>
<body>
<h1>Django + SocketIO Test</h1>
<h2>Send:</h2>
<form id="emit" method="POST" action='#'>
<input type="text" name="emit_data" id="emit_data" placeholder="Message">
<input type="submit" value="Echo">
</form>
<form id="broadcast" method="POST" action='#'>
<input type="text" name="broadcast_data" id="broadcast_data" placeholder="Message">
<input type="submit" value="Broadcast">
</form>
<form id="join" method="POST" action='#'>
<input type="text" name="join_room" id="join_room" placeholder="Room Name">
<input type="submit" value="Join Room">
</form>
<form id="leave" method="POST" action='#'>
<input type="text" name="leave_room" id="leave_room" placeholder="Room Name">
<input type="submit" value="Leave Room">
</form>
<form id="send_room" method="POST" action='#'>
<input type="text" name="room_name" id="room_name" placeholder="Room Name">
<input type="text" name="room_data" id="room_data" placeholder="Message">
<input type="submit" value="Send to Room">
</form>
<form id="close" method="POST" action="#">
<input type="text" name="close_room" id="close_room" placeholder="Room Name">
<input type="submit" value="Close Room">
</form>
<form id="disconnect" method="POST" action="#">
<input type="submit" value="Disconnect">
</form>
<h2>Receive:</h2>
<div><p id="log"></p></div>
</body>
</html>
3 changes: 3 additions & 0 deletions examples/wsgi/django_example/socketio_app/tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from django.test import TestCase

# Create your tests here.
7 changes: 7 additions & 0 deletions examples/wsgi/django_example/socketio_app/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from django.conf.urls import url

from . import views

urlpatterns = [
url(r'', views.index, name='index'),
]
Loading

0 comments on commit 3531b51

Please sign in to comment.