Django-Channels#

Warning

This approach is not recommended anymore, please consider using turbo_stream_from instead.

This library can also be used with django-channels. As with multiple streams, you can use the TurboStream class to broadcast turbo-stream content from your consumers.

from turbo_response import render_turbo_stream, render_turbo_stream_template
from channels.generic.websocket import AsyncJsonWebsocketConsumer

class ChatConsumer(AsyncJsonWebsocketConsumer):

    async def chat_message(self, event):

        # DB methods omitted for brevity
        message = await self.get_message(event["message"]["id"])
        num_unread_messages = await self.get_num_unread_messages()

        if message:
            await self.send(
                TurboStream("unread_message_counter")
                .replace.render(str(num_unread_messages))
            )

            await self.send(
                TurboStream("messages").append.template(
                  "chat/_message.html",
                  {"message": message, "user": self.scope['user']},
                ).render()
            )

See the django-channels documentation for more details on setting up ASGI and channels. Note that you will need to set up your WebSockets in the client, for example in a Stimulus controller:

import { Controller } from 'stimulus';
import { connectStreamSource, disconnectStreamSource } from '@hotwired/turbo';

export default class extends Controller {
  static values = {
    socketUrl: String,
  };

  connect() {
    this.source = new WebSocket(this.socketUrlValue);
    connectStreamSource(this.source);
  }

  disconnect() {
    if (this.source) {
      disconnectStreamSource(this.source);
      this.source.close();
      this.source = null;
    }
  }
}