8. Channels

Lona implements a simple publish/subscribe system, that follows the broker pattern, called channels.

Channels are a powerful tool for creating multi-user features in Lona applications. By allowing users to communicate with each other in soft real-time, channels can be used to create a wide range of collaborative and interactive features, such as real-time chat, collaborative editing, multiplayer games, and more.

Note

soft real-time means "no timing guarantees" in this case. Messages are guaranteed to arrive at every subscribed channel exactly once, in the correct order, but not at a specific time.

This example shows a very simple multi-user chat, implemented using channels. For a more elaborated version take a look at the Multi User Chat demo.

(When trying this demo, choose a chat name via the URL http://localhost:8080/Alice)

from lona_picocss.html import InlineButton, TextArea, HTML, Pre, H1
from lona_picocss import install_picocss

from lona import View, App

app = App(__file__)

install_picocss(app)


@app.route('/<name>')
class Index(View):
    def send_message(self, input_event):
        message = self.text_area.value.strip()

        if not message:
            return

        self.channel.send({
            'name': self.name,
            'message': message,
        })

        self.text_area.value = ''

    def handle_message(self, message):
        self.messages.write_line(
            f"{message.data['name']}: {message.data['message']}",
        )

    def handle_request(self, request):
        self.name = request.match_info['name']

        # setup html
        self.messages = Pre(style='height: 10em')
        self.text_area = TextArea(placeholder='Say something nice')

        self.html = HTML(
            H1(f'Chatting as {self.name}'),
            self.messages,
            self.text_area,
            InlineButton(
                'Send',
                handle_click=self.send_message,
            ),
        )

        # subscribe to channel
        self.channel = self.subscribe(
            topic='chat',
            handler=self.handle_message,
        )

        return self.html


if __name__ == '__main__':
    app.run()

More information: Channels