Added basic websocket funtionality

This commit is contained in:
Gonçalo Valério 2018-11-26 01:05:03 +00:00
parent 24f47f34f3
commit ca4faca497
9 changed files with 179 additions and 14 deletions

View File

@ -10,6 +10,7 @@ pylint = "*"
[packages]
django = "==2.1.3"
channels = "==2.1.5"
channels-redis = "*"
[requires]
python_version = "3.6.7"

88
Pipfile.lock generated
View File

@ -1,7 +1,7 @@
{
"_meta": {
"hash": {
"sha256": "a1a6318c9a51fe4cd91cc030c573f2852081fa92365053bade1dcbbe3c3a96a0"
"sha256": "5f9dc64463611d7dd407577e1531d95730e0dd6a48776dd473f84f4f7a177499"
},
"pipfile-spec": 6,
"requires": {
@ -16,6 +16,13 @@
]
},
"default": {
"aioredis": {
"hashes": [
"sha256:84d62be729beb87118cf126c20b0e3f52d7a42bb7373dc5bcdd874f26f1f251a",
"sha256:aee16aa5cb3f636cf8fa0e2b62d2f6abc90366e19b5c30e94a5471d834a55975"
],
"version": "==1.2.0"
},
"asgiref": {
"hashes": [
"sha256:9b05dcd41a6a89ca8c6e7f7e4089c3f3e76b5af60aebb81ae6d455ad81989c97",
@ -39,10 +46,10 @@
},
"autobahn": {
"hashes": [
"sha256:74914efa7c810323ef838025697024b0858c81a79456c9f581947a2c124c3699",
"sha256:c7e775e46fc033160fa89942de4953ca739f26167f74431dc2c8a3cd165b8755"
"sha256:43262e500aaf8b89fb5f0b60ab13163500ee877908cdd6861208546d95c6dba0",
"sha256:81ee21d654886cccdce01f9f294c71ff2f6ae7b34244e52b522fddc5400736b3"
],
"version": "==18.11.1"
"version": "==18.11.2"
},
"automat": {
"hashes": [
@ -59,6 +66,14 @@
"index": "pypi",
"version": "==2.1.5"
},
"channels-redis": {
"hashes": [
"sha256:3ed68cdb8022484c01e13627804d2e8a238460c9284a3f524a7729cdbb43d403",
"sha256:834bc73b256a4489f400644082cebff276f43164c7202a1b39c14f170b72239b"
],
"index": "pypi",
"version": "==2.3.1"
},
"constantly": {
"hashes": [
"sha256:586372eb92059873e29eba4f9dec8381541b4d3834660707faf8ba59146dfc35",
@ -81,6 +96,39 @@
"index": "pypi",
"version": "==2.1.3"
},
"hiredis": {
"hashes": [
"sha256:0c8cff472d579434c667e4c8243efe1a7f598b1f616f08d12c06770f8e4171c0",
"sha256:3342935cace1000d4a1cb49b4a54c17809ce25f079c32cafb99b9c02c5cca454",
"sha256:36f2f8bd9359845c3dcbfcb0a34eaaf701f11f2a3ee37c44c4661fc7c18c7d7e",
"sha256:40450a48b5345d6e25809c6394f49be9b807c153420d3a8a0e37b73909858cb6",
"sha256:4646f90cdc016741a713867bd13b1d3d58f65375a587aff99eefaca52aa23965",
"sha256:4b18eee6cece99e7fe9cf92f684b75f1ed9bac0441d790be9109b20fc40ba38e",
"sha256:56ca28661eed77ce3452b7df3e67d5edb4e4c9f980d332717b729386182d9d4d",
"sha256:605ed6fe5fcbb118fc10d76d8032026992fbb13f4f2bed5905d6ddcf6e5b0136",
"sha256:61a96b60445ee411388770053298b711a7710db5f550f809820906f119b5612b",
"sha256:66b7d3ba7b960768a119ec1c038a47f3a2cb3b4a7c633a9f1101df519ecb3c6f",
"sha256:6df9b91d326174c68e43fe34e2603260d83d7faacee92a4ccfbbcbd599e5c4e4",
"sha256:75baa5798f72fafe471d12eb3b0de8b6c9fdcef74d446c30442224dfa77c6a54",
"sha256:7b8dd1f19f3ce2f542383d195db936722d57b76adc03c749e7a06f2ffc89e6d6",
"sha256:7cad0f0fe9dd195e59b893808a6c53b77200eebce11165bc04c40a1d8bae4792",
"sha256:8193f0507f992d5c245f12e6c91b87ee748c7f2fe5ba9a90c0b365287e56a118",
"sha256:84095ea3688c9a35f24301ac6eb65fd9c4611f3fc578c312f9f5af3b7085b257",
"sha256:a30c3589bf244ea34cc69cc945f169983dc8b7cd2ccec1da5edfb04eda25656c",
"sha256:a919f7a8c7090d9c801722fd0f9bb8ff2df19152c06bde5aa26b0d38d5d9601a",
"sha256:c63ffba61d2640ec475a35bb267d705b138c9c08ec2050c4c93abe6b547b18b6",
"sha256:cc0bd82e25856764ea3d5f1b362783fadd44ef1b4ed99d04ca34fcefdaf9fc11",
"sha256:cf6dfc793db12c51e4e149b35cbdd2453768123ede0c0f29eadb4cbf214645a2",
"sha256:cfb5eebdac36a53f7c71e3e46f9369105c41ab5ffa2421adab148f2e5c0c7ebf",
"sha256:d38e4f8381836c3b41454a26d92de58b41558c46a31ccb1e7e24b74a9afff2c1",
"sha256:dc38a6067c22a1904d5ebfb241ae0ecf408f09f5018a56af1b1cf22fedb3a948",
"sha256:e3660251762c769b2dc94ef2d516225763914089d3f90757cfbd500b896498ef",
"sha256:e9adb17b3aac52d178e603a8f53051db2016e9a9520c56129ec350960c6423b7",
"sha256:f4c8855c11dcb626dffdf7ba305d8d863c0d4bfa95315ab7559be7d0d6899932",
"sha256:fbffc823f2ab5a39c3eb95728a0a111c90fcb36108b33b28ca9969c478eca137"
],
"version": "==0.3.0"
},
"hyperlink": {
"hashes": [
"sha256:98da4218a56b448c7ec7d2655cb339af1f7d751cf541469bb4fc28c4a4245b34",
@ -102,6 +150,26 @@
],
"version": "==17.5.0"
},
"msgpack": {
"hashes": [
"sha256:0b3b1773d2693c70598585a34ca2715873ba899565f0a7c9a1545baef7e7fbdc",
"sha256:0bae5d1538c5c6a75642f75a1781f3ac2275d744a92af1a453c150da3446138b",
"sha256:0ee8c8c85aa651be3aa0cd005b5931769eaa658c948ce79428766f1bd46ae2c3",
"sha256:1369f9edba9500c7a6489b70fdfac773e925342f4531f1e3d4c20ac3173b1ae0",
"sha256:22d9c929d1d539f37da3d1b0e16270fa9d46107beab8c0d4d2bddffffe895cee",
"sha256:2ff43e3247a1e11d544017bb26f580a68306cec7a6257d8818893c1fda665f42",
"sha256:31a98047355d34d047fcdb55b09cb19f633cf214c705a765bd745456c142130c",
"sha256:8767eb0032732c3a0da92cbec5ac186ef89a3258c6edca09161472ca0206c45f",
"sha256:8acc8910218555044e23826980b950e96685dc48124a290c86f6f41a296ea172",
"sha256:ab189a6365be1860a5ecf8159c248f12d33f79ea799ae9695fa6a29896dcf1d4",
"sha256:cfd6535feb0f1cf1c7cdb25773e965cc9f92928244a8c3ef6f8f8a8e1f7ae5c4",
"sha256:e274cd4480d8c76ec467a85a9c6635bbf2258f0649040560382ab58cabb44bcf",
"sha256:f86642d60dca13e93260187d56c2bef2487aa4d574a669e8ceefcf9f4c26fd00",
"sha256:f8a57cbda46a94ed0db55b73e6ab0c15e78b4ede8690fa491a0e55128d552bb0",
"sha256:fcea97a352416afcbccd7af9625159d80704a25c519c251c734527329bb20d0e"
],
"version": "==0.5.6"
},
"pyhamcrest": {
"hashes": [
"sha256:6b672c02fdf7470df9674ab82263841ce8333fb143f32f021f6cb26f0e512420",
@ -174,10 +242,10 @@
"develop": {
"astroid": {
"hashes": [
"sha256:292fa429e69d60e4161e7612cb7cc8fa3609e2e309f80c224d93a76d5e7b58be",
"sha256:c7013d119ec95eb626f7a2011f0b63d0c9a095df9ad06d8507b37084eada1a8d"
"sha256:35b032003d6a863f5dcd7ec11abd5cd5893428beaa31ab164982403bcb311f22",
"sha256:6a5d668d7dc69110de01cdf7aeec69a679ef486862a0850cc0fd5571505b6b7e"
],
"version": "==2.0.4"
"version": "==2.1.0"
},
"autopep8": {
"hashes": [
@ -244,11 +312,11 @@
},
"pylint": {
"hashes": [
"sha256:1d6d3622c94b4887115fe5204982eee66fdd8a951cf98635ee5caee6ec98c3ec",
"sha256:31142f764d2a7cd41df5196f9933b12b7ee55e73ef12204b648ad7e556c119fb"
"sha256:51f5a52bd31cb2db5b83ff37e3e902460eaa5591dea2739ba5d10d13ec5c5350",
"sha256:fe49f9ada5c8999344ac3a37541e329eaff11d014460065c4128fc94cf5cf140"
],
"index": "pypi",
"version": "==2.1.1"
"version": "==2.2.0"
},
"six": {
"hashes": [

26
callbacks/consumers.py Normal file
View File

@ -0,0 +1,26 @@
from channels.generic.websocket import WebsocketConsumer
from asgiref.sync import async_to_sync
import json
class WebhookConsumer(WebsocketConsumer):
def connect(self):
"""While the connection of open it is associated with a callback"""
self.callback = self.scope['url_route']['kwargs']['uuid']
async_to_sync(self.channel_layer.group_add)(
self.callback, self.channel_name
)
self.accept()
def disconnect(self, close_code):
async_to_sync(self.channel_layer.group_discard)(
self.callback, self.channel_name
)
def receive(self, text_data):
# Discard all received data
pass
def new_request(self, event):
"""Sends all the newly received data on the callback"""
self.send(text_data=json.dumps(event["data"]))

7
callbacks/routing.py Normal file
View File

@ -0,0 +1,7 @@
from django.conf.urls import url
from .consumers import WebhookConsumer
websocket_urlpatterns = [
url(r'^ws/callback/(?P<uuid>[^/]+)/$', WebhookConsumer),
]

View File

@ -0,0 +1,34 @@
function setupConnection() {
/*
Setup a connection to receive all the information
about the webhooks in real-time.
*/
var callbackCode = getCallbackCode();
console.log(callbackCode);
var webhookSocket = new WebSocket(
"ws://" + window.location.host + "/ws/callback/" + callbackCode + "/"
);
webhookSocket.onmessage = function(event) {
/*
Parses the information adds it to the UI state
*/
console.log(event);
};
webhookSocket.onopen = function(event) {
console.log("[Webhook_logger] Connection stablished");
};
webhookSocket.onclose = function(event) {
console.log("[Webhook_logger] Connection lost");
console.log("[Webhook_logger] Trying to reconnect");
setupConnection();
};
}
function getCallbackCode() {
var urlParams = new URLSearchParams(window.location.search);
return urlParams.get("cb");
}
setupConnection();

View File

@ -1,4 +1,4 @@
<!DOCTYPE html>
{% load staticfiles %} <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
@ -6,5 +6,8 @@
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Webhook Logger</title>
</head>
<body></body>
<body>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script src="{% static 'js/viewer.js' %}"></script>
</body>
</html>

View File

@ -1,5 +1,8 @@
from django.views.generic import RedirectView, TemplateView, View
from django.urls import reverse_lazy
from django.http import HttpResponse
from channels.layers import get_channel_layer
from asgiref.sync import async_to_sync
from uuid import uuid4
@ -26,3 +29,14 @@ class CallbackView(View):
This view receives any HTTP request, collects all the information
possible about the request, then sends it through the proper channel
"""
def dispatch(self, request, *args, **kwargs):
channel_layer = get_channel_layer()
async_to_sync(channel_layer.group_send)(
kwargs["uuid"],
{
'type': "new_request",
'data': {"test": "test"}
}
)
return HttpResponse()

View File

@ -1,3 +1,6 @@
from channels.routing import ProtocolTypeRouter
from channels.routing import ProtocolTypeRouter, URLRouter
from callbacks.routing import websocket_urlpatterns
application = ProtocolTypeRouter({})
application = ProtocolTypeRouter({
"websocket": URLRouter(websocket_urlpatterns)
})

View File

@ -97,3 +97,12 @@ STATIC_URL = '/static/'
# Django Channels
ASGI_APPLICATION = "webhook_logger.routing.application"
CHANNEL_LAYERS = {
'default': {
'BACKEND': 'channels_redis.core.RedisChannelLayer',
'CONFIG': {
"hosts": [('127.0.0.1', 6379)],
},
},
}