ppt1
WebSocket
WebSocket is a full-duplex (two-way communication) protocol that is used in the same scenario of client-server communication.
It is a stateful protocol, which means the connection between client and server will keep alive until it is terminated by either client or server, after closing the connection by either of the client and server, the connection is terminated from both the end.
WebSockets do not use the http:// or https:// scheme (because they do not follow the HTTP protocol).
Rather, WebSocket URIs use a new scheme ws: (or wss: for a secure WebSocket).
The remainder of the URI is the same as an HTTP URI: a host, port, path and any query parameters.
Example:- ws://example.com:8000/ws/chat
Configuring Django Channel
gs1- ppt2
Install using pip
pip install channels
Uninstall using pip
pip uninstall channels
Adding Channels to Django Project
INSTALLED_APPS = [
‘channels’,
…
]
asgi.py
from channels.routing import ProtocolTypeRouter
application = ProtocolTypeRouter({
"http": get_asgi_application(),
# Just HTTP for now. (We can add other protocols later.)
})
settings.py
#WSGI_APPLICATION = 'gs1.wsgi.application'
ASGI_APPLICATION = 'gs1.asgi.application'
gs2- ppt3
Consumers
A consumer is the basic unit of Channels code. Consumers are like Django views.
Creating Consumers:-
- SyncConsumer
- AsyncConsumer
1. SyncConsumer
A consumer is a subclass of either SyncConsumer or AsyncConsumer.
SyncConsumer will run your code synchronously in a threadpool.
app/consumers.py
2.AsyncConsumer
AsyncConsumer will expect you to write async-capable code.
app/consumers.py
consumers.py
# Topic - Consumer
from channels.consumer import SyncConsumer, AsyncConsumer
class MySyncConsumer(SyncConsumer):
# This handler is called when client initially opens a connection and is about to finish the WebSocket handshake.
def websocket_connect(self, event):
print('Websocket Connected...')
# This handler is called when data received from Client
def websocket_receive(self, event):
print('Messaged Received...')
# This handler is called when either connection to the client is lost, either from the client closing the connection, the server closing the connection, or loss of the socket.
def websocket_disconnect(self, event):
print('Websocket Disconnected...')
class MyAsyncConsumer(AsyncConsumer):
# This handler is called when client initially opens a connection and is about to finish the WebSocket handshake.
async def websocket_connect(self, event):
print('Websocket Connected...')
# This handler is called when data received from Client
async def websocket_receive(self, event):
print('Messaged Received...')
# This handler is called when either connection to the client is lost, either from the client closing the connection, the server closing the connection, or loss of the socket.
async def websocket_disconnect(self, event):
print('Websocket Disconnected...')
gs3- ppt4
Routing
This is similar to Django’s as_view(), which plays the same role for per-request instances of class-based views.
- Create routing.py File then write all websocket url patterns inside this file.
- Open asgi.py file and mentioned your routing.py file
app/routing.py
from django.urls import path
from . import consumers
websocket_urlpatterns = [
path('ws/sc/', consumers.MySyncConsumer.as_asgi()),
path('ws/ac/', consumers.MyAsyncConsumer.as_asgi()),
]
gs3/asgi.py
import os
from django.core.asgi import get_asgi_application
from channels.routing import ProtocolTypeRouter, URLRouter
import app.routing
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'gs3.settings')
application = ProtocolTypeRouter({
'http': get_asgi_application(),
'websocket': URLRouter(
app.routing.websocket_urlpatterns
)
})
gs4- ppt5
Consumers
A consumer is the basic unit of Channels code. Consumers are like Django views.
Allow you to write synchronous or async code and deals with handoffs and threading for you.
A consumer is a subclass of either SyncConsumer or AsyncConsumer.
- SyncConsumer will run your code synchronously in a threadpool.
- AsyncConsumer will expect you to write async-capable code.
app/consumers.py
# Topic - More on Consumer and Routing
from channels.consumer import SyncConsumer, AsyncConsumer
from channels.exceptions import StopConsumer
class MySyncConsumer(SyncConsumer):
# when client(application) send somthing to the server ai event(message) call, handshake ar aga pajanta
# two way connection enable hoya jaba
def websocket_connect(self, event):
print('Websocket Connected...', event)
# client(application) thaka jata as66a sata accept karar janna
self.send({
'type':'websocket.accept',
})
# when Message received from Client ai event(message) call
def websocket_receive(self, event):
print('Message received from Client', event)
print(event['text'])
# when server send somthing to the client
self.send({
'type':'websocket.send', # for send
'text':'Message Sent to Client' # what server wants to send
})
# when server or client au akjon disconnect kora connection ai event(message) call
def websocket_disconnect(self, event):
print('Websocket Disconnected...', event)
# ata lik66i karon jata error na asa(ata ho66a exception(mana exception handel kor66i))
raise StopConsumer()
class MyAsyncConsumer(AsyncConsumer):
async def websocket_connect(self, event):
print('Websocket Connected...', event)
await self.send({
'type':'websocket.accept',
})
async def websocket_receive(self, event):
print('Message received from Client', event)
print(event['text'])
await self.send({
'type':'websocket.send',
'text':'Message Sent to Client'
})
async def websocket_disconnect(self, event):
print('Websocket Disconnected...', event)
raise StopConsumer()
Real Time Data (syncConsumer vs AsyncConsumer) No ppt gs5
gs6- ppt6
WebSocket
The WebSocket object provides the API for creating and managing a WebSocket connection to a server, as well as for sending and receiving data on the connection.
To construct a WebSocket, use the WebSocket() constructor.
Example:-
var ws = new WebSocket('ws://127.0.0.1:8000/ws/sc/’);
WebSocket Properties
onopen
ws.onopen = function (event) {
console.log("WebSocket Connection open“, event);
};
onmessage
ws.onmessage = function (event) {
console.log("WebSocket message received from server”, event);
};
onerror
ws.onerror = function (event) {
console.log(“WebSocket Error Occurred”, event);
};
onclose
ws.onclose = function (event) {
console.log(“WebSocket Connection Closed”, event);
};
Events
open
ws.addEventListener('open', (event) => {
console.log("WebSocket Connection open");
});
message
ws.addEventListener('message', (event) => {
console.log(' WebSocket message received from server', event);
});
error
ws.addEventListener(‘error', (event) => {
console.log(“WebSocket Error Occurred“, event);
});
close
ws.addEventListener(‘close', (event) => {
console.log('WebSocket connections Closed ', event);
});
Methods
close() – The WebSocket.close() method closes the WebSocket connection or connection attempt, if any. If the connection is already CLOSED, this method does nothing.
Syntax:- ws.close(code, reason)
code - A numeric value indicating the status code explaining why the connection is being closed. If this parameter is not specified, a default value of 1005 is assumed.
reason – A human-readable string explaining why the connection is closing. This string must be no longer than 123 bytes of UTF-8 text (not characters).
Example:- ws.close()
send() – The WebSocket.send() method enqueues the specified data to be transmitted to the server over the WebSocket connection.
If the data can't be sent, the socket is closed automatically.
The browser will throw an exception if you call send() when the connection is in the CONNECTING state.
If you call send() when the connection is in the CLOSING or CLOSED states, the browser will silently discard the data.
Syntax:- ws.send(data)
Example:- ws.send(“Hello”)
consumers.py
# Topic - Web API WebSocket - JavaScript
from channels.consumer import SyncConsumer, AsyncConsumer
from channels.exceptions import StopConsumer
from time import sleep
import asyncio
class MySyncConsumer(SyncConsumer):
def websocket_connect(self, event):
print('Websocket Connected...', event)
self.send({
'type':'websocket.accept',
})
def websocket_receive(self, event):
print('Message received from Client', event)
print(event['text'])
for i in range(10):
self.send({
'type':'websocket.send',
'text': str(i)
})
sleep(1)
def websocket_disconnect(self, event):
print('Websocket Disconnected...', event)
raise StopConsumer()
class MyAsyncConsumer(AsyncConsumer):
async def websocket_connect(self, event):
print('Websocket Connected...', event)
await self.send({
'type':'websocket.accept',
})
async def websocket_receive(self, event):
print('Message received from Client', event)
print(event['text'])
for i in range(50):
await self.send({
'type':'websocket.send',
'text': str(i)
})
await asyncio.sleep(1)
async def websocket_disconnect(self, event):
print('Websocket Disconnected...', event)
raise StopConsumer()
templates\app\index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>Count Page</h1>
<script>
var ws = new WebSocket('ws://127.0.0.1:8000/ws/sc/')
ws.onopen = function () {
console.log('Websocket connection open...')
ws.send('Hi, Message from Client to server...')
}
ws.onmessage = function (event) {
console.log('Message Received from Server...', event)
}
ws.onerror = function (event) {
console.log('Websocket Error Occurred...', event)
}
ws.onclose = function (event) {
console.log('Websocket Connection Closed...', event)
}
// ws.addEventListener('open', (event) => {
// console.log('Websocket connection open...', event)
// ws.send('Hi, Message from Client...')
// })
// ws.addEventListener('message', (event) => {
// console.log('Message Received from Server...', event)
// })
// ws.addEventListener('error', (event) => {
// console.log('Websocket Error Occurred...', event)
// })
// ws.addEventListener('close', (event) => {
// console.log('Websocket Connection Closed...', event)
// })
</script>
</body>
</html>
readyState
gs7
Server Side:-
When Sending Data to Client
Python to String
When Receiving Data from Client
String to Python
Client Side:-
When Sending Data to Server
JavaScript Object to String
When Receiving Data from Server
String to JavaScript Object
Python JSON Lib
In python file used
import json
json.dumps() – This method is used to convert Python dictionary into json string.
json.loads() – This method is used to convert json string into Python dictionary.
JSON
in JavaScript file used
JSON.parse() – This method is used to convert json string into JavaScript object.
JSON.stringify() – This method is used to convert JavaScript object into json string.
gs8 & gs9 - ppt7
Channel Layers
Channel layers allow you to talk between different instances of an application.
It is for high-level application-to-application communication.
We can communicate with out storing data in database.
Most Important this three things- Channels, Groups, Message
Channels - Channels are a first-in, first out queue with at-most-once delivery semantics. Each channel has a name.
Chanal ar nume jana thakla amra message send korta parbo.
Groups - Multiple channel a data send karar janna Groups used kara hoy.
Multiple chanal a data send kara ka bala hoy broadcast system.
Sending to individual channels isn’t particularly useful - in most cases you’ll want to send to multiple channels/consumers there we use groups.
Multiple channels can be grouped into a group. Each group has a name. A channel can be added or removed from a group by anyone who knows the group name. Using the group name you can also send a message to all channels in the group.
Groups are a broadcast system that:
- Allows you to add and remove channel names from named groups, and send message to those named groups.
- Provides group expiry for clean-up of connections.
Messages – Messages must be a dict. Because these messages are sometimes sent over a network, they need to be serializable.
Redis Channel Layer - It is basically use developing purpose and production(So it is recomended to implement and important)
In-Memory Channel Layer - It is basically use developing purpose not used in production
Redis Channel Layer
Redis works as the communication store for the channel layer.
In order to use Redis as a channel layer you have to install channels_redis package.
channels_redis is the only official Django-maintained channel layer supported for production use.
Config Redis Channel Layer
Download and Install Memurai – Redis for Windows alternative
Install channels_redis – pip install channels_redis
Open settings.py file then write
CHANNEL_LAYERS = {
"default": {
"BACKEND": "channels_redis.core.RedisChannelLayer",
"CONFIG": {
"hosts": [("127.0.0.1", 6379)],
},
},
}
get_channel_layer() – This function is used to get default channel layer from a project.
from channels.layers import get_channel_layer
channel_layer – This attribute is used to get default channel layer from a project. This contains a pointer to the channel layer instance, only if you are using consumers.
channel_name – This attribute contains the channel name that will reach the consumer.
Method
send() – It that takes two arguments: the channel to send on, as a unicode string, and the message to send, as a serializable dict.
Syntax:- send(‘channel_name’, message)
group_send() – It takes two positional arguments; the group to send to, as a unicode string, and the message to send, as a serializable dict. It may raise MessageTooLarge but cannot raise ChannelFull.
Syntax:- group_send(‘group_name’, message)
group_add() – This is used to add a channel to a new or existing group. If the channel is already in the group, the function should return normally.
Syntax:- group_add(‘group_name’, ‘channel_name’)
Example:- group_add(‘friends’, self.channel_name)
group_discard() – This is used to remove channel from the group if it is in it, and does nothing otherwise.
Syntax:- group_discard(‘group_name’, ‘channel_name’)
Example:- group_discard(‘friends’, self.channel_name)
Exception
MessageTooLarge, the exception raised when a send operation fails because the encoded message is over the layer’s size limit.
ChannelFull, the exception raised when a send operation fails because the destination channel is over capacity.
gs10 - ppt8
Database
The Django ORM is a synchronous piece of code, and so if you want to access it from asynchronous code you need to do special handling to make sure its connections are closed properly.
If you are writing asynchronous code, however, you will need to call database methods in a safe, synchronous context, using database_sync_to_async.
database_sync_to_async
Write your ORM queries in a separate function or method, and then call it with database_sync_to_async.
Example:-
from channels.db import database_sync_to_async
async def websocket_connect(self):
self.username = await database_sync_to_async(self.get_name)()
def get_name(self):
return User.objects.all()[0].name
gs11- ppt9
Authentication
asgi.py
from channels.auth import AuthMiddlewareStack
application = ProtocolTypeRouter({
'http': get_asgi_application(),
'websocket': AuthMiddlewareStack(
URLRouter(
app.routing.websocket_urlpatterns
) )})
To access the user, just use self.scope["user"] in your consumer
No comments:
Post a Comment