当前位置: 首页 > news >正文

supabase 实现聊天板(Chat Board)

supabase 实现聊天板(Chat Board)

前提条件:windows中部署supabase与测试

1) 初始化数据库(在 Studio 中运行 SQL)

在 Studio -> SQL 编辑器 中执行 dev/data.sql 里新增的聊天表与策略,或复制如下片段:

-- Messages 表和策略(已包含在 dev/data.sql)
create table if not exists public.messages (id bigserial primary key,room text not null default 'public',username text not null default '匿名',content text not null check (char_length(content) > 0),created_at timestamptz not null default now()
);alter table public.messages enable row level security;drop policy if exists "Anyone can read messages" on public.messages;
create policy "Anyone can read messages"on public.messages for select using (true);drop policy if exists "Anyone can send messages" on public.messages;
create policy "Anyone can send messages"on public.messages for insert with check (true);drop policy if exists "Admins can update messages" on public.messages;
create policy "Admins can update messages"on public.messages for update to service_role using (true);drop policy if exists "Admins can delete messages" on public.messages;
create policy "Admins can delete messages"on public.messages for delete to service_role using (true);alter publication supabase_realtime add table public.messages;

2) 快速测试(REST + Realtime)

  • 环境变量设置

    $env:ANON_KEY = ""
    $env:KONG_HTTP_PORT = "8000"
    
  • 拉取最近消息:

    curl.exe -H "apikey: $env:ANON_KEY" -H "Authorization: Bearer $env:ANON_KEY" "http://localhost:$env:KONG_HTTP_PORT/rest/v1/messages?select=*&order=created_at.desc&limit=50"
    
  • 发送消息:

      curl.exe -X POST `-H "Content-Type: application/json" `-H "apikey: $env:ANON_KEY" `-H "Authorization: Bearer $env:ANON_KEY" `-d '{\"room\":\"public\",\"username\":\"张三\",\"content\":\"大家好!\"}' `"http://localhost:$($env:KONG_HTTP_PORT)/rest/v1/messages"
    

3) 最小前端片段(可直接嵌入)

将下列 HTML 保存为 chat.html 并在浏览器中打开(注意将 SUPABASE_URLANON_KEY 替换成你的值):

<!doctype html>
<meta charset="utf-8" />
<title>Chat Board</title>
<script src="https://cdn.jsdelivr.net/npm/@supabase/supabase-js@2"></script>
<style>body { font-family: sans-serif; max-width: 720px; margin: 24px auto; }#messages { border: 1px solid #ddd; padding: 12px; height: 360px; overflow: auto; }#form { display: flex; gap: 8px; margin-top: 12px; }input, button { padding: 8px; }.row { margin: 6px 0; }.time { color: #888; font-size: 12px; margin-left: 8px; }.user { font-weight: bold; }.content { margin-left: 6px; }header { display: flex; justify-content: space-between; align-items: center; }select { padding: 4px; }
</style>
<header><h1>Chat Board</h1><label>Room:<select id="room"><option value="public">public</option><option value="random">random</option></select></label><label>User: <input id="username" value="匿名" /></label>
</header>
<div id="messages"></div>
<div id="form"><input id="input" placeholder="输入消息..." /><button id="send">发送</button><button id="refresh">刷新</button><button id="clear">清屏</button><span id="status"></span></div>
<script>const SUPABASE_URL = 'http://localhost:8000';const ANON_KEY = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE';const sb = supabase.createClient(SUPABASE_URL, ANON_KEY);const $ = (id) => document.getElementById(id);const box = $('messages');const roomSel = $('room');const usernameInput = $('username');const status = $('status');let channel;const isAscii = (s) => /^[\x00-\x7F]+$/.test(s);function validateConfig() {if (!SUPABASE_URL || !ANON_KEY) {status.textContent = '配置缺失:请设置 SUPABASE_URL 和 ANON_KEY';return false;}if (!isAscii(ANON_KEY) || /替换为/.test(ANON_KEY)) {status.textContent = '配置错误:请替换为实际 ANON_KEY(ASCII)';alert('请将 ANON_KEY 替换为实际匿名密钥字符串(ASCII),否则请求会失败。');return false;}return true;}function row({ username, content, created_at }) {const div = document.createElement('div');div.className = 'row';const time = new Date(created_at).toLocaleString();div.innerHTML = `<span class="user">${username}</span><span class="content">${content}</span><span class="time">${time}</span>`;return div;}async function list() {status.textContent = '加载中...';const { data, error } = await sb.from('messages').select('*').eq('room', roomSel.value).order('created_at', { descending: false }).limit(200);status.textContent = error ? '加载失败' : `加载 ${data?.length ?? 0}`;box.innerHTML = '';(data || []).forEach(m => box.appendChild(row(m)));box.scrollTop = box.scrollHeight;}async function send() {const content = $('input').value.trim();if (!content) return;const username = usernameInput.value.trim() || '匿名';const { error } = await sb.from('messages').insert({ room: roomSel.value, username, content });if (error) alert('发送失败: ' + error.message);$('input').value = '';}function subscribe() {if (channel) sb.removeChannel(channel);channel = sb.channel(`room:${roomSel.value}`).on('postgres_changes', { event: 'INSERT', schema: 'public', table: 'messages', filter: `room=eq.${roomSel.value}` }, payload => {box.appendChild(row(payload.new));box.scrollTop = box.scrollHeight;}).subscribe((status) => console.log('subscribe', status));}$('send').onclick = send;$('refresh').onclick = list;$('clear').onclick = () => (box.innerHTML = '');roomSel.onchange = () => { list(); subscribe(); };(async () => { if (!validateConfig()) return; await list(); subscribe(); })();</script>

在这里插入图片描述

http://www.dtcms.com/a/427238.html

相关文章:

  • PersistentVolume + NFS:网络共享存储
  • leetcode 1863 找出所有子集的异或总和再求和
  • 【C++】STL -- vector 的使用及模拟实现
  • 网站如何做图片特效erp软件实施
  • 【28】C# WinForm入门到精通 ——多文档窗体MDI【属性、方法、实例、源码】【多窗口重叠、水平平铺、垂直平铺、窗体传值】
  • 贡井区建设局网站淘宝客做自己的网站
  • 蓝牙发展史
  • 对LED点灯实验的C与汇编的深入分析,提及到volatile
  • 网站建设外包广州网站建设说说外链的建设
  • LevOJ P2080 炼金铺 II [矩阵解法]
  • wordpress网站映射wordpress免费网站国外
  • 哈尔滨企业建站系统西宁建设局官方网站
  • py_innodb_page_info.py表空间分析
  • 有什么做宝宝辅食的网站吗莱阳网站开发
  • tasklet
  • 页面 HTTPS 化实战,从证书部署到真机验证的全流程(证书链、重定向、混合内容、抓包排查)
  • 北京哪家公司做网站电脑上买wordpress
  • 家用机能否做网站服务器泰安房价走势图
  • MC33PT2000控制详解七:软件代码设计1-图形化设置
  • 在租用香港服务器之前如何判断质量
  • 【高清视频】CXL 2.0 over Fibre演示和答疑 - 将内存拉到服务器10米之外
  • 【STM32项目开源】基于STM32的独居老人监护系统
  • 海外服务器怎么测试再不同地方的访问速度?
  • Linux最忙CPU组查找函数和最忙运行队列查找函数
  • 查看未知LiDAR设备的IP地址
  • iOS 0Day漏洞CVE-2025-24085相关PoC利用细节已公开
  • 网站文案框架网络推广策划书
  • 基于Chrome140的FB账号自动化——运行脚本(三)
  • 广州做网站设计镇江建筑公司排名最新
  • RHCA - CL260 | Day12:集群性能建议