213 lines
6.0 KiB
Plaintext
213 lines
6.0 KiB
Plaintext
<template>
|
||
<view class="test-container">
|
||
<text class="title">Supabase Realtime 测试</text>
|
||
<view class="section">
|
||
<text>WS地址></text>
|
||
<input v-model="wsUrl" placeholder="ws(s)://..." />
|
||
</view>
|
||
<view class="section">
|
||
<text>频道></text>
|
||
<input v-model="channel" placeholder="realtime:public:ak_info" />
|
||
</view>
|
||
<view class="section">
|
||
<text>Token></text>
|
||
<input v-model="token" placeholder="可选,JWT" />
|
||
</view>
|
||
<view class="section">
|
||
<button @click="connect">连接</button>
|
||
<button @click="close">断开</button>
|
||
</view>
|
||
<view class="section">
|
||
<button @click="testSignIn">signIn</button>
|
||
</view>
|
||
<view class="section">
|
||
<button @click="subscribeInsert">订阅INSERT</button>
|
||
</view>
|
||
<view class="section">
|
||
<button @click="sendTestMessage">手动发送消息</button>
|
||
</view>
|
||
<view class="section">
|
||
<text>消息></text>
|
||
<scroll-view style="height: 300rpx; border: 1px solid #ccc; padding: 8rpx;" scroll-y>
|
||
<view v-for="(msg, idx) in messages" :key="idx" style="font-size: 24rpx; color: #333; margin-bottom: 8rpx;">
|
||
{{ msg }}
|
||
</view>
|
||
</scroll-view>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script lang="uts">
|
||
import supa from '@/components/supadb/aksupainstance.uts';
|
||
|
||
import { AkSupaRealtime } from '@/components/supadb/aksuparealtime.uts';
|
||
import { AkReq } from '@/uni_modules/ak-req/ak-req.uts';
|
||
import { SUPA_URL, SUPA_KEY ,WS_URL } from '@/ak/config.uts';
|
||
|
||
|
||
export default {
|
||
data() {
|
||
return {
|
||
email: 'akoo@163.com',
|
||
password: 'Hf2152111',
|
||
wsUrl: WS_URL,
|
||
channel: 'realtime:public:ps_push_msg_raw',
|
||
token: '',
|
||
messages: [] as string[],
|
||
realtime: null as AkSupaRealtime | null
|
||
};
|
||
},
|
||
methods: {
|
||
|
||
async testSignIn() {
|
||
try {
|
||
const res = await supa.signIn(this.email, this.password);
|
||
} catch (e) {
|
||
console.log(e)
|
||
}
|
||
},
|
||
connect() {
|
||
|
||
// 先安全关闭 realtime 实例
|
||
const oldRealtime = this.realtime;
|
||
if (oldRealtime != null) {
|
||
oldRealtime.close({}); // 传递空对象,兼容 UTS 类型
|
||
this.realtime = null;
|
||
}
|
||
let token = AkReq.getToken();
|
||
console.log(token);
|
||
if (token == null || token === "") {
|
||
this.messages.push('未检测到 access_token,请先登录');
|
||
return;
|
||
}
|
||
// wsUrl/channel 直接 String(this.wsUrl) 兼容 UTS
|
||
const wsUrl: string = this.wsUrl as string;
|
||
const channel: string = this.channel!!;
|
||
const self = this;
|
||
const newRealtime = new AkSupaRealtime({
|
||
url: wsUrl,
|
||
channel: channel,
|
||
token: token,
|
||
apikey: SUPA_KEY, // 如需 apikey 可补充
|
||
onOpen(res) {
|
||
console.log(res)
|
||
self.messages.push('WebSocket 已连接');
|
||
},
|
||
onClose(res) {
|
||
console.log(res)
|
||
self.messages.push('WebSocket 已断开');
|
||
},
|
||
onError(err) {
|
||
self.messages.push('WebSocket 错误: ' + JSON.stringify(err));
|
||
},
|
||
onMessage(data) {
|
||
self.messages.push('收到消息: ' + JSON.stringify(data));
|
||
}
|
||
});
|
||
this.realtime = newRealtime;
|
||
newRealtime.connect();
|
||
this.messages.push('正在连接...');
|
||
},
|
||
close() {
|
||
const oldRealtime = this.realtime;
|
||
if (oldRealtime != null) {
|
||
oldRealtime.close({}); // 传递空对象,兼容 UTS 类型
|
||
this.realtime = null;
|
||
this.messages.push('手动断开连接');
|
||
}
|
||
},
|
||
subscribeInsert() {
|
||
// 先安全关闭旧实例
|
||
const oldRealtime = this.realtime;
|
||
if (oldRealtime != null) {
|
||
oldRealtime.close({});
|
||
this.realtime = null;
|
||
}
|
||
let token = AkReq.getToken();
|
||
if (!token) {
|
||
this.messages.push('未检测到 access_token,请先登录');
|
||
return;
|
||
}
|
||
const wsUrl: string = this.wsUrl as string;
|
||
// 频道名可自定义为 'elder',事件类型和表名按需传递
|
||
const newRealtime = new AkSupaRealtime({
|
||
url: wsUrl,
|
||
channel: 'elder',
|
||
token: token,
|
||
apikey: SUPA_KEY,
|
||
onOpen: () => {
|
||
this.messages.push('订阅已连接');
|
||
// 订阅 Postgres INSERT 事件
|
||
newRealtime.subscribePostgresChanges({
|
||
event: 'INSERT',
|
||
schema: 'public',
|
||
table: 'ps_push_msg_raw',
|
||
onChange: (payload) => {
|
||
this.messages.push('Change received! ' + JSON.stringify(payload));
|
||
console.log('Change received!', payload);
|
||
}
|
||
});
|
||
},
|
||
onClose: () => {
|
||
this.messages.push('订阅已断开');
|
||
},
|
||
onError: (err) => {
|
||
this.messages.push('订阅错误: ' + JSON.stringify(err));
|
||
},
|
||
onMessage: (data) => {
|
||
console.log(data)
|
||
// 可选:收到其它消息
|
||
}
|
||
});
|
||
this.realtime = newRealtime;
|
||
newRealtime.connect();
|
||
this.messages.push('正在订阅 INSERT...');
|
||
},
|
||
sendTestMessage() {
|
||
if (!this.realtime || !this.realtime.isOpen) {
|
||
this.messages.push('WebSocket 未连接,无法发送');
|
||
return;
|
||
}
|
||
const testMsg = {
|
||
event: 'phx_test',
|
||
payload: { msg: 'Hello from client', time: Date.now() },
|
||
ref: Date.now().toString(),
|
||
topic: this.channel
|
||
};
|
||
this.realtime.send({
|
||
data: testMsg,
|
||
success: (res) => {
|
||
this.messages.push('消息发送成功: ' + JSON.stringify(res));
|
||
},
|
||
fail: (err) => {
|
||
this.messages.push('消息发送失败: ' + JSON.stringify(err));
|
||
}
|
||
});
|
||
},
|
||
}
|
||
};
|
||
</script>
|
||
|
||
<style>
|
||
.test-container {
|
||
padding: 32rpx;
|
||
}
|
||
.title {
|
||
font-size: 36rpx;
|
||
font-weight: bold;
|
||
margin-bottom: 32rpx;
|
||
}
|
||
.section {
|
||
margin-bottom: 24rpx;
|
||
}
|
||
input {
|
||
border: 1px solid #ccc;
|
||
border-radius: 8rpx;
|
||
padding: 8rpx 16rpx;
|
||
margin-left: 12rpx;
|
||
}
|
||
button {
|
||
margin-right: 16rpx;
|
||
}
|
||
</style>
|