WebSocket protocol and HTTP protocol
Introduction to the HTTP protocol
It refers to the HTTP protocol Hypertext Transfer Protocol ( H yper T EXT T ransfer P rotocol), is transmitted from a web server to a hypertext transfer protocol the local browser, the application layer protocol is based on the TCP / IP protocol.
main feature
- Simple and fast : a customer service request to the server, instead of sending the request method and path, the communication speed quickly.
- Flexible : HTTP allows the transmission of any type of data object.
- Connectionless : each connection restriction process only one request. After the server processes client requests and receives the customer's response, i.e., disconnected. In this way it can save transmission time.
- Stateless : HTTP protocol is stateless protocol. No state is no protocol for transaction processing and memory. If the lack of state means that the subsequent processing required in front of the information, it must be retransmitted, which may result in the amount of data transmitted for each connection is increased. On the other hand, when it does not require previous information in response to a faster server.
- Supports client / server model
working principle
HTTP is based on client / server model, and connection-oriented. A typical HTTP transaction has the following process:
-
Customers to establish a connection to the server;
- Customer request to the server;
- Server accepts the request and returns the corresponding file according to a request as a reply;
- Client and server closes the connection.
WebSocket Protocol Overview
Now, many sites in order to achieve push technology, the technology used is Ajax polling. Polling is in a specific time interval (e.g., every 1 second), issues an HTTP request to the server by the browser, and returns the latest data to the client browser by the server. This traditional model brings obvious disadvantage that the browser requires constant request to the server, however, HTTP requests may contain a long head, which truly effective data may only be a small part, obviously this will waste a lot of bandwidth resources.
HTML5 WebSocket protocol definition, better able to save server resources and bandwidth, and can be more real-time communication.
WebSocket is a protocol for full duplex communication over a single TCP connection. WebSocket enables exchange of data between the client and the server easier, allowing the server actively push data to the client . In the WebSocket API, the browser and the server only needs to complete a handshake, directly between the two can create a persistent connection , and two-way data transmission .
Django Channels WebSocket achieve real-time communication
Channels is a function using Django and expand the project to other than HTTP, to handle the WebSocket protocol. It is based on called ASGI the Python build specification.
Next, based on the use of official Tutorial1-2 brief Channels.
First you need to install Django and Channels
pip install django
pip install channels
Create a Django project and enter the project root directory:
django-admin startproject mysite
cd mysite
Next, create the root of routing Channels routing.py
, channels routing configuration similar to Django URLconf, it tells Channels Channels When the server receives what code to run when the HTTP request.
First, an empty routing configuration from the start, create a file mysite/routing.py
that contains the following code:
# mysite/routing.py
from channels.routing import ProtocolTypeRouter
application = ProtocolTypeRouter({
# (http->django views is added by default)
})
Then Channels library to register in the app list:
# mysite/settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
# 新添加
'channels',
]
Continue to edit mtsite/settings.py
the Channels to the root routing configuration, add the following code:
# mysite/settings.py
# Channels
ASGI_APPLICATION = 'mysite.routing.application'
Channels can be controlled at this time runserver
command, instead of the standard developed by Channels server Django development server.
Run Django project:
py manage.py runserver
You will see the following output:
Performing system checks...
System check identified no issues (0 silenced).
You have 17 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
Run 'python manage.py migrate' to apply them.
March 07, 2020 - 22:45:04
Django version 3.0.2, using settings 'mysite.settings'
Starting ASGI/Channels version 2.4.0 development server at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK.
HTTP GET / 200 [0.04, 127.0.0.1:54871]
It can be seen Starting ASGI/Channels development server at http://127.0.0.1:8000/
, indicating Channels development server from Django development server to take over the project. Open the initial screen , you will see the familiar small rocket:
Shut down the server, create App event
:
py manage.py startapp event
Register app:
# mysite/settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'channels',
# 新添加
'event',
]
In the root directory create a new folder templates
and the templates/event
folder to place html file, mysite/settings.py
add the path:
# mysite/settings.py
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
# 修改
'DIRS': [os.path.join(BASE_DIR, 'templates').replace('\\', '/')],
'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',
],
},
},
]
In templates
adding the view file event/list.html
, wherein the requested portion WebSocket template as follows:
<script type="text/javascript">
function Filter() {
if ("WebSocket" in window) {
//alert("您的浏览器支持WebSocket!");
// 重定向URL
let ws = new WebSocket("ws://"+ window.location.host + "/ws/event/list/");
ws.onopen = function () {
ws.send(JSON.stringify({
'message': "测试",
// 需要传输的数据
}));
}
ws.onmessage = function (evt) {
let received_msg = JSON.parse(evt.data);
let feed_back = received_msg['feedback'];
alert(feedback);
// 处理接受数据
}
ws.onclose = function () {
//alert("WebSocket连接已关闭...");
}
}
else {
alert("你的浏览器不支持WebSocket!");
}
}
</script>
Create a view function event/views.py
:
# event/views.py
from django.shortcuts import render
def list(request):
return render(request, 'event/list.html', {})
Create a route event/urls.py
:
# event/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('list/', views.list, name='list'),
]
Will event app
add the route to the root route project:
# mysite/urls.py
from django.conf.urls import include
from django.urls import path
from django.contrib import admin
urlpatterns = [
path('admin/', admin.site.urls),
path('event/', include('event.urls', namespace='event')),
]
Channels processing of the request:
1. Channels接受HTTP请求
2. 查询根URLconf查找**消费者(consumer)**
3. 在**消费者(consumer)**中调用各种功能来处理连接的事件
Create a consumer (consumer) file event/consumers.py
:
event/
__init__.py
……
consumers.py
……
urls.py
views.py
Code templates are as follows:
# event/consumers.py
from channels.generic.websocket import WebsocketConsumer
import json
class ListDataConsumer(WebsocketConsumer):
def connect(self):
self.accept()
def disconnect(self, close_code):
pass
def receive(self, text_data):
# 字典化接收数据
text_data_json = json.loads(text_data)
message = text_data_json['message']
# 数据处理
self.send(text_data=json.dumps({
'feedback': "Accept",
# 返回数据
}))
Is consumers.py
configured to route new event/routing.py
:
# event/routing.py
from django.urls import re_path
from . import consumers
websocket_urlpatterns = [
re_path(r'ws/event/list/$', consumers.ListDataConsumer),
]
Then the root route points to event/routing.py
the file:
# mysite/routing.py
from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter
import event.routing
application = ProtocolTypeRouter({
# (http->django views is added by default)
'websocket': AuthMiddlewareStack(
URLRouter(
event.routing.websocket_urlpatterns
)
),
})
This routing configuration root specified when establishing a connection to the server Channels development, ProtocolTypeRouter
will first check the type of connection. If it is WebSocket connection ( WS: // or WSS: // ), assigned to the connection AuthMiddlewareStack
.
In AuthMiddlewareStack
the filling connection of the range to cover the current user authentication and then connect to URLRouter
. This URLRouter
will be based on research, to provide connectivity to route HTTP path to a particular consumer-based url
model.
After migrating database model:
py manage.py makemigrations
py manage.py migrate
Run the project:
py manage.py runserver
If the connection is established, the background should have the following display:
HTTP GET /event/list/ 200 [0.06, 127.0.0.1:58855]
WebSocket HANDSHAKING /ws/event/list/ [127.0.0.1:58906]
WebSocket CONNECT /ws/event/list/ [127.0.0.1:58906]
to sum up
Channels use the above general procedure, the following configuration ASGI, Channels server will replace the original Django server processes the request.
Only when required for use WebSocket protocol for real-time communication needs to be configured routing.py
and consumers.py
, by the routing.py
point consumers.py
processing WebSocket request, using only the remaining HTTP protocol requests before use and there is no difference .
Because only one app at a project in the use of the Channels, you can refer to the project code of event
.