{"id":21475131,"url":"https://github.com/snapp-incubator/qsse","last_synced_at":"2025-07-15T09:32:12.033Z","repository":{"id":37872343,"uuid":"489619602","full_name":"snapp-incubator/qsse","owner":"snapp-incubator","description":"SSE over QUIC protocol","archived":false,"fork":false,"pushed_at":"2025-05-06T06:49:09.000Z","size":646,"stargazers_count":35,"open_issues_count":1,"forks_count":3,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-06-23T04:41:32.561Z","etag":null,"topics":["go","golang","http3","quic","server-sent-events","sse"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/snapp-incubator.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-05-07T08:46:39.000Z","updated_at":"2025-05-10T00:03:39.000Z","dependencies_parsed_at":"2023-12-12T04:26:15.824Z","dependency_job_id":"a010f117-c9d9-4bca-a57c-c13791340b82","html_url":"https://github.com/snapp-incubator/qsse","commit_stats":null,"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"purl":"pkg:github/snapp-incubator/qsse","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/snapp-incubator%2Fqsse","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/snapp-incubator%2Fqsse/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/snapp-incubator%2Fqsse/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/snapp-incubator%2Fqsse/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/snapp-incubator","download_url":"https://codeload.github.com/snapp-incubator/qsse/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/snapp-incubator%2Fqsse/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265425320,"owners_count":23762900,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["go","golang","http3","quic","server-sent-events","sse"],"created_at":"2024-11-23T10:37:43.289Z","updated_at":"2025-07-15T09:32:11.729Z","avatar_url":"https://github.com/snapp-incubator.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ch1 align=\"center\"\u003e\n  \u003cimg alt=\"QSSE logo\" src=\"assets/icon.png\" width=\"500px\"/\u003e\u003cbr/\u003e\n  SSE Over QUIC\n\u003c/h1\u003e\n\n\u003cp align=\"center\"\u003eImplementation of Server Sent Events by QUIC. A faster replacement for traditional SSE over HTTP/2.\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n\u003ca href=\"https://pkg.go.dev/github.com/snapp-incubator/qsse/v3?tab=doc\"target=\"_blank\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/Go-1.18+-00ADD8?style=for-the-badge\u0026logo=go\" alt=\"go version\" /\u003e\n\u003c/a\u003e\n\u003cimg src=\"https://img.shields.io/badge/license-apache_2.0-red?style=for-the-badge\u0026logo=none\" alt=\"license\" /\u003e\n\u003cimg src=\"https://img.shields.io/badge/Version-1.2.0-informational?style=for-the-badge\u0026logo=none\" alt=\"version\" /\u003e\n\u003c/p\u003e\n\n\n## Installation\n```bash\ngo get github.com/snapp-incubator/qsse\n```\n\n## Basic Usage\n\n### Server\n```Go\n// Server\npackage main\n\nimport \"github.com/snapp-incubator/qsse\"\n\nvar (\n    people = []Person{...}\n    accounts = []Account{...}\n) \n\nfunc main() {\n\ttopics := []string{\"people\", \"account\"}\n\n\tserver, err := qsse.NewServer(\"localhost:4242\", topics, nil)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\t// publish events\n\tserver.Publish(\"people\", people[0])\n\tserver.Publish(\"accounts\", accounts[0])\n\t// ...\n\n\t// some blocking code to keep the server up\n}\n```\n\n### Client\n```Go\npackage main\n\nimport \"github.com/snapp-incubator/qsse\"\n\nfunc main() {\n    topics := []string{\"people\", \"account\"}\n    \n    client, err := qsse.NewClient(\"localhost:4242\", topics, nil)\n    if err != nil {\n        panic(err)\n    }\n\t\n    client.SetEventHandler(\"people\", func(data []byte) {\n        // handle data on topic\n    })\n\t\n    client.SetErrorHandler(func(code int, data map[string]any) { \n        // handle different error\n    })\n\n\t// some blocking code to keep the client up for receiving the events\n}\n```\n\n## Security\nBy default, all the clients are accepted. Use Authentication to check is new clients are valid and use Authorization to check client access on each topic.\n```Go\n// authentication\n\n// func\nserver.SetAuthenticatorFunc(func(token string) bool {\n\n})\n// interface\nserver.SetAuthenticator()\n\n// authorization on each topic\n\n// func\nserver.SetAuthorizerFunc(func(token, topic string) bool {\n\n})\n// interface\nserver.SetAuthorizer()\n```\n\n## Topic Patterns\ntopics can be separated by `.` logically. also `*` can be used as wildcard placeholder. for example these are valid topics \n- `ride`\n- `ride.*.start`\n- `ride.passenger.*` \n\n**Note**: Putting `*` at the end of topic will publish or subscribe to every topic that start with `*` prefix. For example `ride.passenger.*` is equivalent of subscribing to `ride.passenger.start`, `ride.passenger.account.name`, and so on.\n\n## Server Configurations\n| config                                 \t | description                                                                                   \t| default                        \t|\n|------------------------------------------|-----------------------------------------------------------------------------------------------\t|--------------------------------\t|\n| Metric.namespace, \u003cbr\u003eMetric.subsystem \t | namespace and subsystem parameters of the Prometheus metrics                                  \t| \"qsse\",\u003cbr\u003e\"qsse\"              \t|\n| TLSConfig                              \t | TLS config of server                                                                          \t| qsse.GetDefaultTLSConfig\u003cbr\u003e() \t|\n| Worker.CleaningInterval                \t | interval between cleaning idle clients                                                        \t| 10 sec                         \t|\n| Worker.ClientAcceptorCount             \t | number of Goroutine accepting new clients                                                     \t| 1                              \t|\n| Worker.ClientAcceptorQueueSize         \t | queue size of client acceptors. (this is usually equal to `clientAcceptorCount`)              \t| 1                              \t|\n| Worker.EventDistributorCount           \t | number of concurrent goroutine distributing events to subscribers for each EventSource[topic] \t| 1                              \t|\n| Worker.EventDistributorQueueSize       \t | queue size of event distribution work                                                         \t| 10                             \t|\n\n## Client Configurations\n| config                        \t| description                                                                                          \t| default                 \t|\n|-------------------------------\t|------------------------------------------------------------------------------------------------------\t|-------------------------\t|\n| token                         \t| token that will be send to server on the initial connection to verify the client.                    \t| \"\"                      \t|\n| TLSConfig                     \t| TLS config of client                                                                                 \t| qsse.GetSimpleTLS\u003cbr\u003e() \t|\n| ReconnectPolicy.Retry         \t| bool that indicate if client should retry connection if couldn't connect to server on the first try. \t| false                   \t|\n| ReconnectPolicy.RetryTimes    \t| number of reconnect times to connect.                                                                \t| 5                       \t|\n| ReconnectPolicy.RetryInterval \t| interval between reconnecting to server                                                              \t| 5 sec                   \t|\n\n## Examples\n- [Simple Client \u0026 Server](examples/simple)\n- [Topic Patterns](examples/topic-pattern)\n- [Multiple Generators](examples/multiple-generators)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsnapp-incubator%2Fqsse","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsnapp-incubator%2Fqsse","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsnapp-incubator%2Fqsse/lists"}