socket io with fastify

This commit is contained in:
Maieul BOYER 2025-11-18 15:10:32 +01:00 committed by Maix0
parent 34e9f8e3ca
commit 0a504a75ce
6 changed files with 101 additions and 47 deletions

View file

@ -3,24 +3,25 @@ import { showError } from "@app/toast";
import authHtml from './chat.html?raw'; import authHtml from './chat.html?raw';
import client from '@app/api' import client from '@app/api'
import { updateUser } from "@app/auth"; import { updateUser } from "@app/auth";
import io from "socket.io-client" import io from "socket.io-client";
// const socket = io("wss://localhost:8888"); // const socket = io("wss://localhost:8888");
const socket = io("wss://localhost:8888", { const socket = io("wss://local.maix.me:8888", {
path: "/app/chat/socket.io/", path: "/api/chat/socket.io/",
secure: false, secure: true,
transports: ["websocket"], transports: ["websocket"],
}); });
// Listen for the 'connect' event // Listen for the 'connect' event
socket.on("connect", () => { socket.on("connect", async () => {
console.log("Connected to the server: ", socket.id); console.log("Connected to the server: ", socket.id);
// Send a message to the server
socket.send("Hello from the client: " + `${socket.id}`);
// Emit a custom event 'coucou' with some data // Emit a custom event 'coucou' with some data
socket.emit("coucou", { message: "Hello Nigel from coucou!" }); socket.emit("coucou", { message: "Hello Nigel from coucou!" });
console.log('sent coucou');
// Send a message to the server
socket.send("Hello from the client: " + `${socket.id}`);
}); });
@ -33,33 +34,31 @@ type Providers = {
}; };
function handleChat(_url: string, _args: RouteHandlerParams): RouteHandlerReturn { function handleChat(_url: string, _args: RouteHandlerParams): RouteHandlerReturn {
setTitle('Chat Page'); setTitle('Chat Page');
// Listen for the 'connect' event // Listen for the 'connect' event
return { return {
html: authHtml, postInsert: async (app) => { html: authHtml, postInsert: async (app) => {
const sendButton = document.getElementById('b-send') as HTMLButtonElement; const sendButton = document.getElementById('b-send') as HTMLButtonElement;
const chatWindow = document.getElementById('t-chatbox') as HTMLDivElement; const chatWindow = document.getElementById('t-chatbox') as HTMLDivElement;
const sendtextbox= document.getElementById('t-chat-window') as HTMLButtonElement; const sendtextbox = document.getElementById('t-chat-window') as HTMLButtonElement;
const blogout = document.getElementById('b-logout') as HTMLButtonElement; const blogout = document.getElementById('b-logout') as HTMLButtonElement;
const bwhoami = document.getElementById('b-whoami') as HTMLButtonElement; const bwhoami = document.getElementById('b-whoami') as HTMLButtonElement;
const username = document.getElementById('username') as HTMLDivElement; const username = document.getElementById('username') as HTMLDivElement;
const value = await client.chatTest(); const value = await client.chatTest();
if (value.kind === "success") if (value.kind === "success") {
{
console.log(value.payload); console.log(value.payload);
} }
else if (value.kind === "notLoggedIn") else if (value.kind === "notLoggedIn") {
{
} else { } else {
console.log('unknown response: ', value); console.log('unknown response: ', value);
} }
// Add a new message to the chat display // Add a new message to the chat display
const addMessage = (text: any) => { const addMessage = (text: any) => {
const messageElement = document.createElement('div'); const messageElement = document.createElement('div');
@ -67,16 +66,16 @@ function handleChat(_url: string, _args: RouteHandlerParams): RouteHandlerReturn
chatWindow.appendChild(messageElement); chatWindow.appendChild(messageElement);
chatWindow.scrollTop = chatWindow.scrollHeight; //puts scroll to the bottom chatWindow.scrollTop = chatWindow.scrollHeight; //puts scroll to the bottom
}; };
sendButton!.addEventListener('click', async () => {
let msgtext: string = sendtextbox.value;
if (msgtext) { sendButton!.addEventListener('click', async () => {
addMessage(msgtext); let msgtext: string = sendtextbox.value;
if (msgtext) {
addMessage(msgtext);
sendtextbox.value = ""; sendtextbox.value = "";
} }
}); });
chatWindow.textContent = "helloWorld"; chatWindow.textContent = "helloWorld";
// Whoami button to display user name // Whoami button to display user name
@ -103,10 +102,10 @@ function handleChat(_url: string, _args: RouteHandlerParams): RouteHandlerReturn
} }
} }
}; };
addRoute('/chat', handleChat, { bypass_auth: true }); addRoute('/chat', handleChat, { bypass_auth: true });

View file

@ -10,9 +10,5 @@ location /api/chat/socket.io/ {
proxy_set_header Connection "Upgrade"; proxy_set_header Connection "Upgrade";
proxy_set_header Host $host; proxy_set_header Host $host;
proxy_read_timeout 3600s; proxy_read_timeout 3600s;
root /volumes/static/chat; proxy_pass http://chat;
proxy_pass http://chat$uri;
# proxy_pass http://chat;
} }

View file

@ -28,6 +28,7 @@
"fastify": "^5.6.2", "fastify": "^5.6.2",
"fastify-cli": "^7.4.1", "fastify-cli": "^7.4.1",
"fastify-plugin": "^5.1.0", "fastify-plugin": "^5.1.0",
"fastify-socket.io": "^5.1.0",
"socket.io": "^4.8.1" "socket.io": "^4.8.1"
}, },
"devDependencies": { "devDependencies": {

View file

@ -5,6 +5,8 @@ import * as db from '@shared/database';
import * as auth from '@shared/auth'; import * as auth from '@shared/auth';
import * as swagger from '@shared/swagger'; import * as swagger from '@shared/swagger';
import * as utils from '@shared/utils'; import * as utils from '@shared/utils';
import { Server } from 'socket.io';
import useSocketIo from 'fastify-socket.io';
declare const __SERVICE_NAME: string; declare const __SERVICE_NAME: string;
@ -15,8 +17,12 @@ const routes = import.meta.glob('./routes/**/*.ts', { eager: true });
// When using .decorate you have to specify added properties for Typescript // When using .decorate you have to specify added properties for Typescript
declare module 'fastify' { declare module 'fastify' {
export interface FastifyInstance { interface FastifyInstance {
image_store: string; io: Server<{
hello: (message: string) => string,
coucou: (data: { message: string }) => void,
message: (msg: string) => void,
}>
} }
} }
@ -27,6 +33,9 @@ const app: FastifyPluginAsync = async (fastify, opts): Promise<void> => {
await fastify.register(db.useDatabase as FastifyPluginAsync, {}); await fastify.register(db.useDatabase as FastifyPluginAsync, {});
await fastify.register(auth.jwtPlugin as FastifyPluginAsync, {}); await fastify.register(auth.jwtPlugin as FastifyPluginAsync, {});
await fastify.register(auth.authPlugin as FastifyPluginAsync, {}); await fastify.register(auth.authPlugin as FastifyPluginAsync, {});
await fastify.register(useSocketIo, {
path: '/api/chat/socket.io',
});
// Place here your custom code! // Place here your custom code!
for (const plugin of Object.values(plugins)) { for (const plugin of Object.values(plugins)) {
@ -39,6 +48,22 @@ const app: FastifyPluginAsync = async (fastify, opts): Promise<void> => {
void fastify.register(fastifyFormBody, {}); void fastify.register(fastifyFormBody, {});
void fastify.register(fastifyMultipart, {}); void fastify.register(fastifyMultipart, {});
fastify.get('/monitoring', () => 'Ok'); fastify.get('/monitoring', () => 'Ok');
fastify.ready((err) => {
if (err) throw err;
fastify.io.on('connection', (socket) => {
console.info('Socket connected!', socket.id);
socket.on('hello', (value) => {
console.log(`GOT HELLO ${value}`);
return 'hi';
});
socket.on('message', (value) => console.log(`GOT MESSAGE ${value}`));
socket.on('coucou', (value) => console.log(`GOT COUCOU ${value.message}`));
},
);
});
}; };
export default app; export default app;

View file

@ -1,26 +1,23 @@
import { FastifyPluginAsync } from 'fastify'; import { FastifyPluginAsync } from 'fastify';
import { MakeStaticResponse, typeResponse } from '@shared/utils'; import { MakeStaticResponse, typeResponse } from '@shared/utils';
import { Type } from '@sinclair/typebox'; import { Type } from '@sinclair/typebox';
import Fastify from 'fastify' import Fastify from 'fastify';
import { Server } from "socket.io" import { Server } from 'socket.io';
import { Socket } from "socket.io"; import { Socket } from 'socket.io';
import * as fsocketio from 'fastify-socket.io';
const fastify = Fastify(); const fastify = Fastify();
const io = new Server(fastify.server, { const io = new Server(fastify.server, {
path: "/app/chat/socket.io/", path: '/app/chat/socket.io/',
cors: { origin: "*" }, cors: { origin: '*' },
}); });
io.on('connection', (socket: Socket) => {
io.on("connection", (socket: Socket) => { console.log('testing');
console.log("testing") console.log(`Client connected: ${socket.id}`);
console.log(`Client connected: ${socket.id}`);
socket.on("message", (data: any) => console.log(data, `socketID: ${socket.id}`));
socket.once("message", () => socket.send("connected succesfully"));
socket.once("coucou", (data: any) => console.log(data))
}); });
@ -32,9 +29,24 @@ export const ChatRes = {
}), }),
}; };
export type ChatResType = MakeStaticResponse<typeof ChatRes>; export type ChatResType = MakeStaticResponse<typeof ChatRes>;
const route: FastifyPluginAsync = async (fastify): Promise<void> => { const route: FastifyPluginAsync = async (fastify): Promise<void> => {
/* await fastify.register(fsocketio.default);
fastify.get('/api/chat/socket.io', (req, reply) => {
console.log('GOT SOCKET ?!');
const socket = (fastify as any).io;
socket.emit('hello');
socket.on('message', (data: any) => console.log(data, `socketID: ${socket.id}`));
socket.once('message', () => socket.send('connected succesfully'));
socket.once('coucou', (data: any) => console.log(data));
});
*/
fastify.get( fastify.get(
'/api/chat/test', '/api/chat/test',
{ {

21
src/pnpm-lock.yaml generated
View file

@ -179,6 +179,9 @@ importers:
fastify-plugin: fastify-plugin:
specifier: ^5.1.0 specifier: ^5.1.0
version: 5.1.0 version: 5.1.0
fastify-socket.io:
specifier: ^5.1.0
version: 5.1.0(fastify@5.6.2)(socket.io@4.8.1)
socket.io: socket.io:
specifier: ^4.8.1 specifier: ^4.8.1
version: 4.8.1 version: 4.8.1
@ -1788,9 +1791,18 @@ packages:
resolution: {integrity: sha512-7Jsfj2uLuGWvnxjrGDrHWpSm65+OcVx0ZbTD2wwkz6Wt6KjGm6+ZYwwpdXdwAlzbJYq+LCEMNvDJc4485AQ1vQ==} resolution: {integrity: sha512-7Jsfj2uLuGWvnxjrGDrHWpSm65+OcVx0ZbTD2wwkz6Wt6KjGm6+ZYwwpdXdwAlzbJYq+LCEMNvDJc4485AQ1vQ==}
hasBin: true hasBin: true
fastify-plugin@4.5.1:
resolution: {integrity: sha512-stRHYGeuqpEZTL1Ef0Ovr2ltazUT9g844X5z/zEBFLG8RYlpDiOCIG+ATvYEp+/zmc7sN29mcIMp8gvYplYPIQ==}
fastify-plugin@5.1.0: fastify-plugin@5.1.0:
resolution: {integrity: sha512-FAIDA8eovSt5qcDgcBvDuX/v0Cjz0ohGhENZ/wpc3y+oZCY2afZ9Baqql3g/lC+OHRnciQol4ww7tuthOb9idw==} resolution: {integrity: sha512-FAIDA8eovSt5qcDgcBvDuX/v0Cjz0ohGhENZ/wpc3y+oZCY2afZ9Baqql3g/lC+OHRnciQol4ww7tuthOb9idw==}
fastify-socket.io@5.1.0:
resolution: {integrity: sha512-GC1gjrxBGeTbMWV779XHF4uw3AtgKwSQJ9MnjGiMp91ZBuPXEdBYa7NnAMDEl3oZPgK9JO4BlNncTV+UAN+1kg==}
peerDependencies:
fastify: 4.x.x
socket.io: '>=4'
fastify@5.6.2: fastify@5.6.2:
resolution: {integrity: sha512-dPugdGnsvYkBlENLhCgX8yhyGCsCPrpA8lFWbTNU428l+YOnLgYHR69hzV8HWPC79n536EqzqQtvhtdaCE0dKg==} resolution: {integrity: sha512-dPugdGnsvYkBlENLhCgX8yhyGCsCPrpA8lFWbTNU428l+YOnLgYHR69hzV8HWPC79n536EqzqQtvhtdaCE0dKg==}
@ -4899,8 +4911,17 @@ snapshots:
semver: 7.7.3 semver: 7.7.3
yargs-parser: 22.0.0 yargs-parser: 22.0.0
fastify-plugin@4.5.1: {}
fastify-plugin@5.1.0: {} fastify-plugin@5.1.0: {}
fastify-socket.io@5.1.0(fastify@5.6.2)(socket.io@4.8.1):
dependencies:
fastify: 5.6.2
fastify-plugin: 4.5.1
socket.io: 4.8.1
tslib: 2.8.1
fastify@5.6.2: fastify@5.6.2:
dependencies: dependencies:
'@fastify/ajv-compiler': 4.0.5 '@fastify/ajv-compiler': 4.0.5