foxglove / ws-protocol

Foxglove Studio WebSocket protocol specification and libraries

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Listener does not trigger on_subscribe() event

aeon0 opened this issue · comments

commented

Description
Running the sample code does not trigger a subscribe event for me when I connect with foxglove studio to the websocket server.

  • Version: 1.73.0
  • Platform: Linux for webserver, Windows for studio

Steps To Reproduce

import asyncio
from typing import Set, Type
from base64 import b64encode
from foxglove_websocket.server import FoxgloveServer, FoxgloveServerListener
from foxglove_websocket.types import ChannelId, ChannelWithoutId
import google.protobuf.message
from google.protobuf.descriptor_pb2 import FileDescriptorSet
from google.protobuf.descriptor import FileDescriptor

from foxglove_websocket import run_cancellable
from foxglove_schemas_protobuf.SceneUpdate_pb2 import SceneUpdate


def build_file_descriptor_set(
    message_class: Type[google.protobuf.message.Message],
) -> FileDescriptorSet:
    """
    Build a FileDescriptorSet representing the message class and its dependencies.
    """
    file_descriptor_set = FileDescriptorSet()
    seen_dependencies: Set[str] = set()

    def append_file_descriptor(file_descriptor: FileDescriptor):
        for dep in file_descriptor.dependencies:
            if dep.name not in seen_dependencies:
                seen_dependencies.add(dep.name)
                append_file_descriptor(dep)
        file_descriptor.CopyToProto(file_descriptor_set.file.add())  # type: ignore

    append_file_descriptor(message_class.DESCRIPTOR.file)
    return file_descriptor_set


class Listener(FoxgloveServerListener):
    async def on_subscribe(self, server: FoxgloveServer, channel_id: ChannelId):
        print(f"SUBSCRIBED {channel_id}")


async def main():
    server = FoxgloveServer("0.0.0.0", 8765, "example server")
    server.start()
    server.set_listener(Listener())

    topic_name = "sample"
    schema_type = SceneUpdate
    sample = await server.add_channel(
        ChannelWithoutId(
            topic=topic_name,
            encoding="protobuf",
            schemaName=schema_type.DESCRIPTOR.full_name,
            schema=b64encode(build_file_descriptor_set(schema_type).SerializeToString()).decode("ascii"),
            schemaEncoding="protobuf",
        )
    )

    print("Start loop")
    while True:
        await asyncio.sleep(0.05)


if __name__ == "__main__":
    run_cancellable(main())

Expected Behavior
The on_subscription event should be triggered. Confusingly if I create CompressedImage channels in the same way I get the callback triggered.

commented

I found this behaviour:

I have to do sth with the data e.g. show it as raw messages before the callback is called. Is this expected behaviour?

Yes, on_subscribe does not mean a client has just connected to the server, it means the data on this channel is actually requested by the client. Does that make sense?

I tested out your sample script and it appears to be behaving as expected (see my previous comment).