Supabase Realtime
通过WebSocket发送临时消息、追踪和同步共享状态,以及监听Postgres变更。
多人演示
·
请求新功能
·
报告错误
状态
功能 | v1 | v2 | 状态 |
---|---|---|---|
Postgres 变更 | ✔ | ✔ | 正式版 |
广播 | ✔ | 测试版 | |
在线状态 | ✔ | 测试版 |
本仓库主要关注第2版,但你仍可以访问之前版本的代码和Docker镜像。最新的Docker镜像请访问https://hub.docker.com/r/supabase/realtime。
代码库正在快速开发中,文档也在不断完善。欢迎试用并通过创建issue告诉我们你的想法。关注本仓库的releases以获取更新通知。如果你喜欢这个项目,请给我们一个星标!
概述
这是什么?
这是一个使用Phoenix框架构建的Elixir服务器,提供以下功能:
- 广播:以低延迟从客户端向客户端发送临时消息。
- 在线状态:追踪和同步客户端之间的共享状态。
- Postgres变更:监听Postgres数据库变更并将其发送给授权的客户端。
更详细的概述请查看Realtime指南。
这个服务器能保证消息送达吗?
服务器不保证每条消息都会被送达到你的客户端,使用Realtime时请记住这一点。
快速开始
你可以查看多人演示,它展示了广播、在线状态和Postgres变更功能。演示代码位于:https://github.com/supabase/realtime/tree/main/demo。
客户端库
- JavaScript: @supabase/realtime-js
- Dart: @supabase/realtime-dart
服务器设置
首先,启动docker-compose.yml
中定义的Postgres数据库和Realtime服务器容器。例如,你可以运行docker-compose -f docker-compose.yml up
。
注意 Supabase在生产环境中使用单独的数据库来跟踪所有租户。但是,为了简化本地开发,当通过
docker-compose.yml
启动容器时,会创建一个_realtime
模式。
系统已为你添加了一个租户。你可以通过检查数据库中的_realtime.tenants
和_realtime.extensions
表来确认这一点。
你可以通过向服务器发送POST
请求来添加自己的租户。你必须更改name
和external_id
,其他值可以根据需要更新:
curl -X POST \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiIiLCJpYXQiOjE2NzEyMzc4NzMsImV4cCI6MTcwMjc3Mzk5MywiYXVkIjoiIiwic3ViIjoiIn0._ARixa2KFUVsKBf3UGR90qKLCpGjxhKcXY4akVbmeNQ' \
-d $'{
"tenant" : {
"name": "realtime-dev",
"external_id": "realtime-dev",
"jwt_secret": "a1d99c8b-91b6-47b2-8f3c-aa7d9a9ad20f",
"extensions": [
{
"type": "postgres_cdc_rls",
"settings": {
"db_name": "postgres",
"db_host": "host.docker.internal",
"db_user": "postgres",
"db_password": "postgres",
"db_port": "5432",
"region": "us-west-1",
"poll_interval_ms": 100,
"poll_max_record_bytes": 1048576
}
}
]
}
}' \
http://localhost:4000/api/tenants
注意
Authorization
令牌使用docker-compose.yml
中API_JWT_SECRET
设置的密钥签名。
如果你想监听Postgres变更,可以创建一个表,然后将该表添加到supabase_realtime
发布中:
create table test (
id serial primary key
);
alter publication supabase_realtime add table test;
你可以使用客户端库(如@supabase/realtime-js
)或使用本地主机上的内置Realtime检查器http://localhost:4000/inspector/new
(确保端口与你的开发环境一致)开始使用广播、在线状态和Postgres变更功能。
WebSocket URL必须包含子域名(_realtime.tenants
表中租户的external_id
),令牌必须使用与租户一起插入的jwt_secret
签名。
如果你使用默认租户,URL为ws://realtime-dev.localhost:4000/socket
(确保端口与你的开发环境一致),你可以使用eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MDMwMjgwODcsInJvbGUiOiJwb3N0Z3JlcyJ9.tz_XJ89gd6bN8MBpCl7afvPrZiBH6RB65iA1FadPT3Y
作为令牌。令牌必须包含exp
和role
(数据库角色)键。
环境变量
变量 | 类型 | 描述 |
---|---|---|
PORT | 数字 | 客户端/监听器可以连接的端口 |
DB_HOST | 字符串 | 数据库主机URL |
DB_PORT | 数字 | 数据库端口 |
DB_USER | 字符串 | 数据库用户 |
DB_PASSWORD | 字符串 | 数据库密码 |
DB_NAME | 字符串 | Postgres数据库名称 |
DB_ENC_KEY | 字符串 | 用于加密_realtime.tenants和_realtime.extensions表中敏感字段的密钥。建议:16个字符。 |
DB_AFTER_CONNECT_QUERY | 字符串 | 服务器连接到数据库后运行的查询。 |
API_JWT_SECRET | 字符串 | 用于签署通过HTTP请求管理租户及其扩展的令牌的密钥。 |
SECRET_KEY_BASE | 字符串 | 服务器用于签署cookie的密钥。建议:64个字符。 |
ERL_AFLAGS | 字符串 | 根据你的网络使用IPv4还是IPv6,设置为"-proto_dist inet_tcp"或"-proto_dist inet6_tcp"。 |
APP_NAME | 字符串 | 服务器的名称。 |
DNS_NODES | 字符串 | 在集群中运行服务器时使用的节点名称。 |
MAX_CONNECTIONS | 字符串 | 设置WebSocket连接的软上限。默认为'16384'。 |
MAX_HEADER_LENGTH | 字符串 | 设置连接的最大头部长度(以字节为单位)。默认为'4096'。 |
NUM_ACCEPTORS | 字符串 | 设置将中继传入WebSocket连接请求的服务器进程数量。默认为'100'。 |
DB_QUEUE_TARGET | 字符串 | 从连接池获取连接的最长等待时间。默认为'5000'或5秒。更多信息请参见:DBConnection。 |
DB_QUEUE_INTERVAL | 字符串 | 检查是否所有连接都在DB_QUEUE_TARGET下被检出的间隔。如果在此间隔内所有连接都超过了目标时间,则目标时间会加倍。默认为'5000'或5秒。更多信息请参见:DBConnection。 |
DB_POOL_SIZE | 字符串 | 设置数据库连接池中的连接数。默认为'5'。 |
SLOT_NAME_SUFFIX | 字符串 | 这会附加到复制槽,允许创建自定义槽名。可以包含小写字母、数字和下划线字符。与默认的supabase_realtime_replication_slot 一起,槽名应不超过64个字符。 |
TENANT_MAX_BYTES_PER_SECOND | 字符串 | 首次创建租户时使用的每个租户支持的每秒最大字节数的默认值。默认为'100_000'。 |
TENANT_MAX_CHANNELS_PER_CLIENT | 字符串 | 首次创建租户时使用的每个租户支持的最大通道数的默认值。默认为'100'。 |
TENANT_MAX_CONCURRENT_USERS | 字符串 | 首次创建租户时使用的每个租户支持的每个通道的最大并发用户数的默认值。默认为'200'。 |
TENANT_MAX_EVENTS_PER_SECOND | 字符串 | 首次创建租户时使用的每个租户支持的每秒最大事件数的默认值。默认为'100'。 |
TENANT_MAX_JOINS_PER_SECOND | 字符串 | 首次创建租户时使用的每个租户支持的每秒最大通道加入数的默认值。默认为'100'。 |
SEED_SELF_HOST | 布尔值 | 使用默认租户为系统播种 |
WebSocket URL
本地开发时,WebSocket URL的格式如下:ws://[external_id].localhost:4000/socket/websocket
如果你在生产环境中使用Supabase托管的Realtime,URL为wss://[project-ref].supabase.co/realtime/v1/websocket?apikey=[anon-token]&log_level=info&vsn=1.0.0"
WebSocket连接授权
WebSocket连接通过对称JWT验证进行授权。仅支持使用以下算法签名的JWT:
- HS256
- HS384
- HS512
通过设置JWT_CLAIM_VALIDATORS来验证JWT声明:
例如 {'iss': 'Issuer', 'nbf': 1610078130}
然后JWT的"iss"值必须等于"Issuer","nbf"值必须等于1610078130。
注意:
JWT过期会自动检查。
exp
和role
(数据库角色)键是必需的。
授权客户端连接:您可以按照实时客户端库中的说明传递JWT。例如,请参阅@supabase/realtime-js客户端库的使用部分。
错误操作代码
这是可以帮助您理解部署和使用情况的操作代码列表。
代码 | 描述 |
---|---|
RealtimeDisabledForConfiguration | 提供给Realtime连接的配置将无法提供任何Postgres更改 |
TenantNotFound | 您尝试连接的租户不存在 |
ErrorConnectingToWebsocket | 尝试连接WebSocket服务器时出错 |
ErrorAuthorizingWebsocket | 尝试授权WebSocket连接时出错 |
TableHasSpacesInName | 您尝试监听的表名中包含空格,我们无法支持 |
UnableToDeleteTenant | 尝试删除租户时出错 |
UnableToSetPolicies | 设置授权策略时出错 |
UnableCheckoutConnection | 尝试从租户池中检出连接时出错 |
UnableToSubscribeToPostgres | 尝试订阅Postgres更改时出错 |
ChannelRateLimitReached | 您可以创建的通道数量已达到限制 |
ConnectionRateLimitReached | 已连接客户端的数量已达到限制 |
ClientJoinRateLimitReached | 客户端每秒加入的速率已达到通道限制 |
UnableToConnectToTenantDatabase | Realtime无法连接到租户的数据库 |
RealtimeNodeDisconnected | Realtime是一个分布式应用程序,这意味着系统无法与其中一个分布式节点通信 |
MigrationsFailedToRun | 对Realtime所需的租户数据库运行迁移时出错 |
ErrorStartingPostgresCDCStream | 启动用于Postgres更改的Postgres CDC流时出错 |
UnknownDataProcessed | Realtime系统处理了未知的数据类型 |
ErrorStartingPostgresCDC | 启动用于Postgres更改的Postgres CDC扩展时出错 |
ReplicationSlotBeingUsed | 复制槽正被另一个事务使用 |
PoolingReplicationPreparationError | 准备复制槽时出错 |
PoolingReplicationError | 池化复制槽时出错 |
SubscriptionDeletionFailed | 尝试删除Postgres更改订阅时出错 |
UnableToDeletePhantomSubscriptions | 尝试删除不再使用的订阅时出错 |
UnableToCheckProcessesOnRemoteNode | 尝试检查远程节点上的进程时出错 |
UnableToCreateCounter | 尝试创建计数器以跟踪租户的速率限制时出错 |
UnableToIncrementCounter | 尝试增加计数器以跟踪租户的速率限制时出错 |
UnableToDecrementCounter | 尝试减少计数器以跟踪租户的速率限制时出错 |
UnableToUpdateCounter | 尝试更新计数器以跟踪租户的速率限制时出错 |
UnableToFindCounter | 尝试查找计数器以跟踪租户的速率限制时出错 |
UnhandledProcessMessage | Realtime进程收到未处理的消息 |
UnableToProcessListenPayload | NOTIFY操作中发送的有效负载无法解析为JSON |
UnableToListenToTenantDatabase | 无法监听租户数据库的通知 |
UnprocessableEntity | 收到的HTTP请求主体无法被端点处理 |
ErrorOnRpcCall | 调用另一个realtime节点时出错 |
ErrorExecutingTransaction | 在租户数据库中执行事务时出错 |
UnknownError | 发生未知错误 |
许可证
此仓库采用Apache 2.0许可。
致谢
- Phoenix -
Realtime
服务器是使用这个出色的Elixir框架构建的。 - Phoenix Channels JavaScript Client - @supabase/realtime-js客户端库很大程度上借鉴了Phoenix Channels客户端库。