Skip to content

Instantly share code, notes, and snippets.

@milansimek
Last active May 22, 2023 13:42
Show Gist options
  • Save milansimek/f801793fe102c8b4c61ebf1def97ae84 to your computer and use it in GitHub Desktop.
Save milansimek/f801793fe102c8b4c61ebf1def97ae84 to your computer and use it in GitHub Desktop.
SvelteKit websockets integration
// src/hooks.server.js
// This initializes the server socket events
// It calls an empty class method to make sure the import isn't removed by Vite when optimizing
// because serverSocketEvents is initialized here, it has access to the svelte app (stores etc)
// (When using hooks.websocket.js for some reason svelte stores, singletons etc weren't shared with the other parts of the app )
import { serverSocketEvents } from '$lib/server/socketio/serverSocketEvents.js';
export async function handle({ event, resolve })
{
serverSocketEvents.init();
return await resolve(event)
}
// src/lib/server/ioserver.js
// Socket IO server singleton
// This initializes the server and exports the instantiated object
import { Server } from 'socket.io';
import { createServer } from "http";
class IoServer {
httpServer = null;
server = null;
constructor() {
this.initServer();
}
initServer() {
this.httpServer = createServer();
this.server = new Server(this.httpServer);;
this.httpServer.listen(3001).on('error', (e) => { });
}
on(event, callback) {
this.server.on(event, callback);
}
broadcast(event, data) {
this.server.broadcast.emit(event, data);
}
emit(event, data) {
this.server.emit(event, data);
}
}
//IMPORTANT: returns instantiated object which will make it a singleton
export const ioServer = new IoServer();
// src/lib/server/socketio/serverSocketEvents.js
// Used to attach events to server
// Also a singleton so it will be initialized only once
// It's possible to create multiple classes with this same format
// This could be used to organize the events per type / room etc instead of using one big file
// This file loads the ioserver singleton
// (I included some of my project code that's by no means ready, but you get the point :) )
import { ioServer } from '$lib/server/socketio/ioserver.js';
import { PrintQueue } from "$lib/repository/printQueue.js"; // <-- This could be a svelte store
class socketIoServerEvents {
eventsAttached = false;
constructor() {
this.#attachEvents();
}
init() { }
#attachEvents() {
if (this.eventsAttached) return;
this.eventsAttached = true;
ioServer.on('connection', (socket) => {
this.#attachSocketEvents(socket);
});
}
#attachSocketEvents(socket) {
socket.on('connect', () => {
console.log('connect');
})
socket.on('addPrintRow', () => {
ioServer.broadcast('addCountServer', 'addCount');
});
socket.on('clearQueue', () => {
PrintQueue.deleteAll(); // <-- here saving to a svelte store would be possible
ioServer.emit('forceSetQueueItems', []);
});
socket.on('addRow', () => {
let fakeData = {
id: 'job_' + Math.random().toString(36).substr(2, 5),
}
let newItem = PrintQueue.newItem( fakeData, true); // <-- here saving to a svelte store would be possible
ioServer.emit('printJobAdded', {
item: newItem.getData()
});
});
socket.on('newJob', (data, callback) => {
console.log('newJob', data)
let status = 'success';
let message = '';
let newItem = {};
try{
newItem = PrintQueue.newItem( data, true); // <-- here saving to a svelte store would be possible
console.log('ni',newItem);
ioServer.emit('printJobAdded', {
item: newItem.getData()
});
}
catch(e){
status = 'error';
message = e.message;
}
callback({ status, message, newItem });
//todo error handling
});
socket.onAny((event, ...args) => {
// console.log(event, args);
});
}
}
export const serverSocketEvents = new socketIoServerEvents();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment