Websocket server command
The message will appear on the tab room tabs.
Show sources
urls.pyfrom hypergen.hypergen import autourls
from websockets import views
app_name = 'websockets'
urlpatterns = autourls(views, app_name)
views.pyfrom hypergen.imports import *
from website.templates2 import base_example_template, show_sources
### chat ###
# Channels urls are not (yet) reversible the same as vanilla urls. Little helper to add protocol and port.
chat_ws_url = lambda: ws_url("/ws/chat/hypergen/")
@liveview(perm=NO_PERM_REQUIRED, base_template=base_example_template)
def chat(request):
h3("Websockets chat")
p("Open multiple tabs to see messages pushed out to all listening consumers.")
# Open a websocket on the client. Can be closed at any point with: command("hypergen.websocket.close", url)
command("hypergen.websocket.open", chat_ws_url())
# Some custom styling.
style(""" input, textarea {width: 100%} """)
# The consumer will write here.
with p(id="counter"):
raw(" ")
# The input field where the user types the chat message.
input_(
id_="message",
type_="text",
placeholder="Write your message here and press enter.",
autofocus=True,
# This callbacks goes to the ChatConsumer in websockets.consumers, because the url starts with "ws://"
# or "wss://".
# Will only trigger when the user presses Enter.
onkeyup=callback(chat_ws_url(), "chat__message_from_frontend", THIS, when=["hypergen.when.keycode", "Enter"],
clear=True),
)
# Chat messages are shown here.
ul(id_="messages")
# Backend send.
p("Visit", a("this page", href=send_message_from_backend.reverse(), target="_blank"),
"to try sending a chat message from the backend.", sep=" ", end=".")
show_sources(__file__)
@liveview(perm=NO_PERM_REQUIRED, base_template=base_example_template)
def send_message_from_backend(request):
from websockets.consumers import ChatConsumer
group_send(ChatConsumer.group_name, {"type": "chat__message_from_backend", "message": "Server message!"})
h2("Websocket server command")
p("The message will appear on the tab room tabs.")
show_sources(__file__)
consumers.pyfrom hypergen.imports import *
class ChatConsumer(HypergenWebsocketConsumer):
group_name = "websockets__consumers__ChatConsumer"
# django-channels will automatically subscribe the consumer to these groups.
groups = [group_name]
# Receives the data sent from the onkeyup callback in views.py.
def receive_hypergen_callback(self, event_type, *args):
if event_type == "chat__message_from_frontend":
message, = args
assert type(message) is str
message = message.strip()[:1000]
if message:
commands = self.update_page(message)
# Send commands to entire group.
self.group_send_hypergen_commands(self.group_name, commands)
# ... More event types goes here.
def chat__message_from_backend(self, event):
commands = self.update_page(event["message"])
# Send commands to individual channel.
self.channel_send_hypergen_commands(commands)
def update_page(self, message):
return hypergen(self.template, message, settings=dict(action=True, returns=COMMANDS, target_id="counter"))
# Render the HTML and issue custom commands.
def template(self, message):
# Writes into the "counter" id.
span("Length of last message is: ", len(message))
# Appends the message to the list of messages. Uses hypergen() directly to render into a string of HTML.
command("hypergen.append", "messages", hypergen(lambda: li(message)))
routing.pyfrom hypergen.imports import NO_PERM_REQUIRED
from django.urls import path
from websockets import consumers
websocket_urlpatterns = [path(r'ws/chat/<slug:room_name>/', consumers.ChatConsumer.as_asgi(perm=NO_PERM_REQUIRED))]