mirror of
https://github.com/SrIzan10/hctv.git
synced 2026-06-06 00:56:56 +00:00
feat: improved viewercount
This commit is contained in:
@@ -7,6 +7,7 @@ import { getCookie } from 'hono/cookie';
|
||||
import { getPersonalChannel } from './utils/personalChannel.js';
|
||||
import { getRedisConnection, prisma, type User } from '@hctv/db';
|
||||
import uFuzzy from '@leeoniya/ufuzzy';
|
||||
import { randomString } from './utils/randomString.js';
|
||||
|
||||
const redis = getRedisConnection();
|
||||
const MESSAGE_HISTORY_SIZE = 15;
|
||||
@@ -68,8 +69,6 @@ app.get(
|
||||
return;
|
||||
}
|
||||
|
||||
// ignoring user here which might be undefined so
|
||||
|
||||
const { username } = c.req.param();
|
||||
if (dbGrant && dbGrant?.name !== username) {
|
||||
ws.close();
|
||||
@@ -77,6 +76,7 @@ app.get(
|
||||
}
|
||||
ws.targetUsername = username;
|
||||
ws.user = user;
|
||||
ws.viewerId = randomString(10);
|
||||
if (ws.raw) {
|
||||
ws.raw.targetUsername = username;
|
||||
// @ts-ignore
|
||||
@@ -96,18 +96,6 @@ app.get(
|
||||
})
|
||||
);
|
||||
}
|
||||
if (token && grant === 'null') {
|
||||
await prisma.streamInfo.update({
|
||||
where: {
|
||||
username,
|
||||
},
|
||||
data: {
|
||||
viewers: {
|
||||
increment: 1,
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
async onClose(evt, ws) {
|
||||
// if prematurely exiting due to authentication issues
|
||||
@@ -125,18 +113,12 @@ app.get(
|
||||
|
||||
if (!streamInfo) return;
|
||||
|
||||
await prisma.streamInfo.update({
|
||||
where: {
|
||||
username: ws.targetUsername,
|
||||
},
|
||||
data: {
|
||||
viewers: streamInfo.viewers === 0 ? { set: 0 } : { decrement: 1 },
|
||||
},
|
||||
});
|
||||
await redis.del(`viewer:${ws.targetUsername}:${ws.viewerId}`);
|
||||
},
|
||||
async onMessage(evt, ws) {
|
||||
const msg = JSON.parse(evt.data.toString());
|
||||
if (msg.type === 'ping') {
|
||||
await redis.setex(`viewer:${ws.targetUsername}:${ws.viewerId}`, 30, '1');
|
||||
ws.send(
|
||||
JSON.stringify({
|
||||
type: 'pong',
|
||||
|
||||
8
apps/chat/src/utils/randomString.ts
Normal file
8
apps/chat/src/utils/randomString.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
export function randomString(length: number): string {
|
||||
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
||||
let result = '';
|
||||
for (let i = 0; i < length; i++) {
|
||||
result += chars.charAt(Math.floor(Math.random() * chars.length));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -621,7 +621,7 @@ export default function ChannelSettingsClient({
|
||||
<div>
|
||||
<h3 className="text-lg font-semibold mb-2">Chat overlay</h3>
|
||||
<p className="text-sm text-mantle-foreground mb-4">
|
||||
Add a 300x600 browser source with this and enjoy!
|
||||
Add a 300x600 browser source with this and enjoy!
|
||||
</p>
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="relative flex-1">
|
||||
|
||||
@@ -33,4 +33,11 @@ export async function register() {
|
||||
const { emojisWriteRedis } = await import('@/lib/instrumentation/emojisWriteRedis');
|
||||
await emojisWriteRedis();
|
||||
}
|
||||
|
||||
if (process.env.NEXT_RUNTIME === 'nodejs') {
|
||||
const { viewerCountSync } = await import('@/lib/instrumentation/viewerCountSync');
|
||||
setInterval(async () => {
|
||||
await viewerCountSync();
|
||||
}, 2000);
|
||||
}
|
||||
}
|
||||
|
||||
22
apps/web/src/lib/instrumentation/viewerCountSync.ts
Normal file
22
apps/web/src/lib/instrumentation/viewerCountSync.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import { getRedisConnection, prisma } from "@hctv/db";
|
||||
|
||||
export async function viewerCountSync() {
|
||||
const streams = await prisma.streamInfo.findMany({
|
||||
include: {
|
||||
channel: true
|
||||
}
|
||||
})
|
||||
const redis = getRedisConnection();
|
||||
|
||||
for (const stream of streams) {
|
||||
const viewerCount = await redis.keys(`viewer:${stream.channel.name}:*`);
|
||||
await prisma.streamInfo.update({
|
||||
where: {
|
||||
username: stream.username,
|
||||
},
|
||||
data: {
|
||||
viewers: viewerCount.length,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -248,6 +248,7 @@ interface ModifiedWSContext extends WSContext<ModifiedWebSocket> {
|
||||
targetUsername?: string;
|
||||
user?: any;
|
||||
personalChannel?: any;
|
||||
viewerId?: string;
|
||||
}
|
||||
|
||||
export interface ModifiedWebSocket extends WebSocket {
|
||||
|
||||
Reference in New Issue
Block a user