replace ws with socketio
This commit is contained in:
@@ -1,3 +1,19 @@
|
||||
- templateVersion: 1.0.0
|
||||
defaultVersion: 9.2.3
|
||||
type: grafana
|
||||
name: Grafana
|
||||
description: >-
|
||||
Grafana allows you to query, visualize, alert on and understand your metrics
|
||||
no matter where they are stored.
|
||||
services:
|
||||
$$id:
|
||||
image: grafana/grafana:$$core_version
|
||||
environment: []
|
||||
volumes:
|
||||
- $$id-config:/etc/grafana
|
||||
- $$id-grafana:/var/lib/grafana
|
||||
variables: []
|
||||
documentation: https://hub.docker.com/r/grafana/grafana
|
||||
- templateVersion: 1.0.0
|
||||
defaultVersion: 1.0.3
|
||||
type: appwrite
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
"@fastify/jwt": "6.3.2",
|
||||
"@fastify/multipart": "7.3.0",
|
||||
"@fastify/static": "6.5.0",
|
||||
"@fastify/websocket": "^7.1.0",
|
||||
"@iarna/toml": "2.2.5",
|
||||
"@ladjs/graceful": "3.0.2",
|
||||
"@prisma/client": "4.5.0",
|
||||
@@ -40,6 +39,7 @@
|
||||
"execa": "6.1.0",
|
||||
"fastify": "4.9.2",
|
||||
"fastify-plugin": "4.3.0",
|
||||
"fastify-socket.io": "4.0.0",
|
||||
"generate-password": "1.7.0",
|
||||
"got": "12.5.2",
|
||||
"is-ip": "5.0.0",
|
||||
@@ -52,7 +52,8 @@
|
||||
"p-throttle": "5.0.0",
|
||||
"prisma": "4.5.0",
|
||||
"public-ip": "6.0.1",
|
||||
"pump": "^3.0.0",
|
||||
"pump": "3.0.0",
|
||||
"socket.io": "4.5.3",
|
||||
"ssh-config": "4.1.6",
|
||||
"strip-ansi": "7.0.1",
|
||||
"unique-names-generator": "4.7.1"
|
||||
@@ -60,7 +61,6 @@
|
||||
"devDependencies": {
|
||||
"@types/node": "18.11.6",
|
||||
"@types/node-os-utils": "1.3.0",
|
||||
"@types/ws": "^8.5.3",
|
||||
"@typescript-eslint/eslint-plugin": "5.41.0",
|
||||
"@typescript-eslint/parser": "5.41.0",
|
||||
"esbuild": "0.15.12",
|
||||
@@ -71,6 +71,7 @@
|
||||
"prettier": "2.7.1",
|
||||
"rimraf": "3.0.2",
|
||||
"tsconfig-paths": "4.1.0",
|
||||
"types-fastify-socket.io": "0.0.1",
|
||||
"typescript": "4.8.4"
|
||||
},
|
||||
"prisma": {
|
||||
|
||||
@@ -6,9 +6,10 @@ import cookie from '@fastify/cookie';
|
||||
import multipart from '@fastify/multipart';
|
||||
import path, { join } from 'path';
|
||||
import autoLoad from '@fastify/autoload';
|
||||
import websocket from '@fastify/websocket';
|
||||
import socketIO from 'fastify-socket.io'
|
||||
import socketIOServer from './realtime'
|
||||
|
||||
import { asyncExecShell, cleanupDockerStorage, createRemoteEngineConfiguration, decrypt, encrypt, executeDockerCmd, executeSSHCmd, generateDatabaseConfiguration, getDomain, isDev, listSettings, prisma, startTraefikProxy, startTraefikTCPProxy, version } from './lib/common';
|
||||
import { asyncExecShell, cleanupDockerStorage, createRemoteEngineConfiguration, decrypt, encrypt, executeDockerCmd, executeSSHCmd, generateDatabaseConfiguration, isDev, listSettings, prisma, startTraefikProxy, startTraefikTCPProxy, version } from './lib/common';
|
||||
import { scheduler } from './lib/scheduler';
|
||||
import { compareVersions } from 'compare-versions';
|
||||
import Graceful from '@ladjs/graceful'
|
||||
@@ -18,8 +19,7 @@ import { verifyRemoteDockerEngineFn } from './routes/api/v1/destinations/handler
|
||||
import { checkContainer } from './lib/docker';
|
||||
import { migrateServicesToNewTemplate } from './lib';
|
||||
import { refreshTags, refreshTemplates } from './routes/api/v1/handlers';
|
||||
import { realtime } from './routes/realtime';
|
||||
import cuid from 'cuid';
|
||||
|
||||
declare module 'fastify' {
|
||||
interface FastifyInstance {
|
||||
config: {
|
||||
@@ -109,23 +109,12 @@ const host = '0.0.0.0';
|
||||
});
|
||||
fastify.register(cookie)
|
||||
fastify.register(cors);
|
||||
fastify.register(websocket, {
|
||||
options: {
|
||||
clientTracking: true,
|
||||
verifyClient: async (info, next) => {
|
||||
try {
|
||||
const token = info.req.headers?.cookie.split('; ').find((cookie) => cookie.startsWith('token')).split('=')[1];
|
||||
if (!token) {
|
||||
return next(false)
|
||||
}
|
||||
fastify.jwt.verify(token)
|
||||
} catch (error) {
|
||||
return next(false)
|
||||
}
|
||||
next(true)
|
||||
}
|
||||
fastify.register(socketIO, {
|
||||
cors: {
|
||||
origin: "http://localhost:3000"
|
||||
}
|
||||
})
|
||||
|
||||
// To detect allowed origins
|
||||
// fastify.addHook('onRequest', async (request, reply) => {
|
||||
// let allowedList = ['coolify:3000'];
|
||||
@@ -148,20 +137,8 @@ const host = '0.0.0.0';
|
||||
|
||||
|
||||
try {
|
||||
fastify.decorate('wssend', function (data: any) {
|
||||
fastify.websocketServer.clients.forEach((client) => {
|
||||
client.send(JSON.stringify(data));
|
||||
})
|
||||
})
|
||||
fastify.register(async function (fastify) {
|
||||
fastify.get('/realtime', { websocket: true }, (connection) => {
|
||||
// connection.socket.on('message', message => {
|
||||
// realtime(fastify, connection, message)
|
||||
// })
|
||||
})
|
||||
})
|
||||
|
||||
await fastify.listen({ port, host })
|
||||
await socketIOServer(fastify)
|
||||
console.log(`Coolify's API is listening on ${host}:${port}`);
|
||||
|
||||
await migrateServicesToNewTemplate()
|
||||
|
||||
@@ -146,18 +146,18 @@ export async function startService(request: FastifyRequest<ServiceStartStop>, fa
|
||||
}
|
||||
async function startServiceContainers(fastify, id, teamId, dockerId, composeFileDestination) {
|
||||
try {
|
||||
fastify.wssend({ teamId, type: 'service', id, message: 'Pulling images...' })
|
||||
fastify.io.to(teamId).emit(`start-service`, { serviceId: id, state: 'Pulling images...' })
|
||||
await executeDockerCmd({ dockerId, command: `docker compose -f ${composeFileDestination} pull` })
|
||||
} catch (error) { }
|
||||
fastify.wssend({ teamId, type: 'service', id, message: 'Building...' })
|
||||
fastify.io.to(teamId).emit(`start-service`, { serviceId: id, state: 'Building images...' })
|
||||
await executeDockerCmd({ dockerId, command: `docker compose -f ${composeFileDestination} build --no-cache` })
|
||||
fastify.wssend({ teamId, type: 'service', id, message: 'Creating containers...' })
|
||||
fastify.io.to(teamId).emit(`start-service`, { serviceId: id, state: 'Creating containers...' })
|
||||
await executeDockerCmd({ dockerId, command: `docker compose -f ${composeFileDestination} create` })
|
||||
fastify.wssend({ teamId, type: 'service', id, message: 'Starting containers...' })
|
||||
fastify.io.to(teamId).emit(`start-service`, { serviceId: id, state: 'Starting containers...' })
|
||||
await executeDockerCmd({ dockerId, command: `docker compose -f ${composeFileDestination} start` })
|
||||
await asyncSleep(1000);
|
||||
await executeDockerCmd({ dockerId, command: `docker compose -f ${composeFileDestination} up -d` })
|
||||
fastify.wssend({ teamId, type: 'service', id, message: 'ending' })
|
||||
fastify.io.to(teamId).emit(`start-service`, { serviceId: id, state: 0 })
|
||||
}
|
||||
export async function migrateAppwriteDB(request: FastifyRequest<OnlyId>, reply: FastifyReply) {
|
||||
try {
|
||||
|
||||
29
apps/api/src/realtime/index.ts
Normal file
29
apps/api/src/realtime/index.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
|
||||
export default async (fastify) => {
|
||||
fastify.io.use((socket, next) => {
|
||||
const { token } = socket.handshake.auth;
|
||||
if (token && fastify.jwt.verify(token)) {
|
||||
next();
|
||||
} else {
|
||||
return next(new Error("unauthorized event"));
|
||||
}
|
||||
});
|
||||
fastify.io.on('connection', (socket: any) => {
|
||||
const { token } = socket.handshake.auth;
|
||||
const { teamId } = fastify.jwt.decode(token);
|
||||
socket.join(teamId);
|
||||
console.info('Socket connected!', socket.id)
|
||||
console.info('Socket joined team!', teamId)
|
||||
socket.on('message', (message) => {
|
||||
console.log(message)
|
||||
})
|
||||
socket.on('error', (err) => {
|
||||
console.log(err)
|
||||
})
|
||||
})
|
||||
// fastify.io.on("error", (err) => {
|
||||
// if (err && err.message === "unauthorized event") {
|
||||
// fastify.io.disconnect();
|
||||
// }
|
||||
// });
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
export function realtime(fastify, connection, message) {
|
||||
const { socket } = connection
|
||||
const data = JSON.parse(message);
|
||||
if (data.type === 'subscribe') {
|
||||
socket.send(JSON.stringify({ type: 'subscribe', message: 'pong' }))
|
||||
}
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -43,14 +43,14 @@
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
"@sveltejs/adapter-static": "1.0.0-next.46",
|
||||
"@tailwindcss/typography": "^0.5.7",
|
||||
"@tailwindcss/typography": "0.5.7",
|
||||
"cuid": "2.1.8",
|
||||
"daisyui": "2.33.0",
|
||||
"dayjs": "1.11.6",
|
||||
"js-cookie": "3.0.1",
|
||||
"js-yaml": "4.1.0",
|
||||
"p-limit": "4.0.0",
|
||||
"svelte-file-dropzone": "^1.0.0",
|
||||
"socket.io-client": "4.5.3",
|
||||
"svelte-select": "4.4.7",
|
||||
"sveltekit-i18n": "2.2.2"
|
||||
}
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
import { dev } from '$app/env';
|
||||
import cuid from 'cuid';
|
||||
import Cookies from 'js-cookie';
|
||||
import {getAPIUrl} from '$lib/api';
|
||||
import {getDomain} from '$lib/common'
|
||||
import { getAPIUrl } from '$lib/api';
|
||||
import { getDomain } from '$lib/common'
|
||||
import { writable, readable, type Writable } from 'svelte/store';
|
||||
import { io as ioClient } from 'socket.io-client';
|
||||
const socket = ioClient(getAPIUrl(), { auth: { token: Cookies.get('token') }, autoConnect: false });
|
||||
|
||||
export const io = socket;
|
||||
interface AppSession {
|
||||
isRegistrationEnabled: boolean;
|
||||
ipv4: string | null,
|
||||
@@ -171,50 +174,3 @@ type State = {
|
||||
export const state = writable<State>({
|
||||
requests: [],
|
||||
});
|
||||
export const connect = () => {
|
||||
const token = Cookies.get('token')
|
||||
if (token) {
|
||||
let url = `wss://${window.location.hostname}/realtime`
|
||||
if (dev) {
|
||||
const apiUrl = getDomain(getAPIUrl())
|
||||
url = `ws://${apiUrl}/realtime`
|
||||
}
|
||||
const ws = new WebSocket(url);
|
||||
ws.addEventListener("message", (message: any) => {
|
||||
appSession.subscribe((session: any) => {
|
||||
const data: Request = { ...JSON.parse(message.data), timestamp: message.timeStamp };
|
||||
if (data.teamId === session.teamId) {
|
||||
if (data.type === 'service') {
|
||||
const ending = data.message === "ending"
|
||||
status.update((status: any) => ({
|
||||
...status,
|
||||
service: {
|
||||
...status.service,
|
||||
startup: {
|
||||
...status.service.startup,
|
||||
...(ending ? { [data.id]: undefined } : { [data.id]: data.message })
|
||||
}
|
||||
}
|
||||
}))
|
||||
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
});
|
||||
ws.addEventListener('open', (event) => {
|
||||
ws.send(JSON.stringify({ type: 'subscribe', message: 'ping' }))
|
||||
});
|
||||
ws.addEventListener('error', (event) => {
|
||||
console.log('error with ws');
|
||||
console.log(event)
|
||||
});
|
||||
ws.addEventListener('close', (event) => {
|
||||
if (!ws || ws.readyState == 3) {
|
||||
setTimeout(() => {
|
||||
connect()
|
||||
}, 1000)
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -81,7 +81,7 @@
|
||||
export let permission: string;
|
||||
export let isAdmin: boolean;
|
||||
|
||||
import{ status, connect } from '$lib/store';
|
||||
import { status, io } from '$lib/store';
|
||||
import '../tailwind.css';
|
||||
import Cookies from 'js-cookie';
|
||||
import { fade } from 'svelte/transition';
|
||||
@@ -110,7 +110,14 @@
|
||||
}
|
||||
}
|
||||
onMount(async () => {
|
||||
connect();
|
||||
io.connect();
|
||||
io.on('start-service', (message) => {
|
||||
const { serviceId, state } = message;
|
||||
$status.service.startup[serviceId] = state;
|
||||
if (state === 0 || state === 1) {
|
||||
delete $status.service.startup[serviceId];
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user