@virgodev/websocket-support
v1.0.1
Published
provides a uniform system for sending and receiving websocket messages
Downloads
1
Keywords
Readme
Virgodev Websocket Support
provides a uniform system for sending and receiving websocket messages
Project Goals
- [x] documentation for connecting django-channels
- [x] support functions for making django-channels easy
- [x] signal for when a message is received
- [x] create a function to send messages to a user
- [x] create a function to send messages to a group
Get Started
Install virgodev_websocket_support and add the websocket support libraries
pip install virgodev_websocket_support pip install daphne uvicorn websockets
Add INSTALLED_APPS setting
INSTALLED_APPS = ( "daphne", # install at the top to convert `runserver` into a websocket client "django.contrib.auth", "django.contrib.contenttypes", "django.contrib.sessions", "django.contrib.sites", "virgodev_websocket_support", ... )
Add ASGI_APPLICATION setting
ASGI_APPLICATION = 'virgodev_websocket_support.asgi.application'
or use the asgi from your own application's asgi file
from virgodev_websocket_support.asgi import application as app
application = app
Add CHANNEL_LAYERS setting
assign the host to the same redis instance as your cache
CHANNEL_LAYERS = { "default": { "BACKEND": "channels_redis.core.RedisChannelLayer", "CONFIG": { "hosts": [CACHES["default"]["LOCATION"]], "group_expiry": 60 * 10, }, }, }
Websocket communication
login clients
use the socketLogin
function to set the token as soon as you recieve it
The token will be used to login immediately if the socket is already connected,
and will be used each time the socket reconnects
import { socketLogin } from '@virgodev/websocket-support'
socketLogin('5de4ffe3df2434140cda6afb27aa3e684d13c65b');
You can use the async property socket.isLoggedIn
to check if the socket has logged in
communicate from server to client
you can send a message to everyone, specific users, or a group by using send_message
events are arbitrary. Make up events for your own use
from virgodev_websocket_support.utils import send_message, send_message_to_everyone
bob = User.objects.get(username="Bob")
group = Group.objects.get(name="Hatfields")
send_message_to_everyone(event='chat', message=dict(msg="hello everyone!"))
send_message(recipients=[bob, group], event='chat', message=dict(msg="hello everyone!"))
You can send messages to specific users or groups as strings as well
send_message(recipients=['everyone', 'user.1', 'group.1'], ...)
On the client side you can catch messages using the socket directly
import { getSocket } from '@virgodev/websocket-support'
const socket = getSocket('<host-or-leave-black-to-call-home>');
socket.on('chat', (msg) => { console.log(msg.msg); });
or use the component:
<script>
import WebsocketIndicator from '@virgodev/websocket-support';
</script>
<template>
<websocket-indicator @chat="handleChat" />
</template>
Then indicator will show an X when it isn't connected
communicate from client to server
It is advised to have clients send messages via the normal rest api
Production
Install and use uvicorn for production websocket handling. Don't forget to add the current version to your requirements file
pip install uvicorn
In your product-py3.conf file, add a websocket catch to make it run websockets
# route websockets to uvicorn
route = ^/ws/ httpdumb://%d../web.socket
# spawn the uvicorn server
# modify your project asgi as needed
attach-daemon = DJANGO_SETTINGS_MODULE=project.settings.development uvicorn --uds web.socket project.asgi:application
or create a supervisor conf
[fcgi-program:<your-project>]
socket=tcp://0.0.0.0:10964
env=DJANGO_SETTINGS_MODULE=project.settings.production
directory=%(here)s/..
command=%(here)s/../venv-<yourvenv>/bin/uvicorn --fd 0 project.asgi:application
numprocs=4
process_name=uvicorn-%(process_num)d
redirect_stderr=true
redirect_stdout=true
user=www-data
group=www-data
chown=www-data
chmod=777
Troubleshooting
If your websockets connect but immediately reject, it could be because you are missing the correct setting for ALLOWED_HOSTS