razshare / sveltekit-sse

Server Sent Events with SvelteKit
https://www.npmjs.com/package/sveltekit-sse
MIT License
301 stars 9 forks source link

Errors on deploy to node.js #29

Closed CyberNinja2007 closed 8 months ago

CyberNinja2007 commented 8 months ago

Hello! I've tried to create my simple app with messages that are saving to the PostgreSQL. There I have two pages - one is for creating them and the other is for viewing. On the viewing page I'm using this package to dynamically update messages without refreshing the page. When I work in dev and preview modes everything is alright, but when I try to build the app, I have some troubles. In builded app, I can see the server is receiving the messages and I can see that it is trying to send this data to the client, but nothing appears. After some time (1 minute maybe), I see this in console, but don't see any errors on server, just messages that connection is closed: изображение After that is again freezed for some time and this thing repeats. Or it can get the updates, but only when the connection closing and I'm trying to recconect, after that it can again get errors. My code is somthing like that:

// /routes/api/messages/server.ts

import { events } from 'sveltekit-sse';
import { createClient } from '$lib/server/db.js';

const updatedMessages:string[] = [];

const clientUpdate = createClient();
await clientUpdate.connect();
await clientUpdate.query('LISTEN messages_update');

clientUpdate.on('notification', (notification) => {
    console.log('New message:', notification);
    if (notification.payload) updatedMessages.push(notification.payload);
});

export function POST({ request, locals }) {
    return events({
        request,
        headers: {
            'Access-Control-Allow-Origin': '*'
        },
        timeout: 90 * 1000,
        async start({ emit, lock }) {
            if (!locals.authedUser) {
                lock.set(false);
                return function cancel() {
                    console.log('Not authorized.');
                };
            }

            const updateInterval = setInterval(async () => {
                if(updatedMessages.length > 0){
                    console.log("Sending new messages...");
                    updatedMessages.forEach((message, index) => {
                        const { error } = emit('updated', message);
                        if (error) {
                            console.error('There is an error while sending messages - ', error);
                            return;
                        }

                        updatedMessages.splice(index, 1);
                    });
                }

                await clientUpdate.query('SELECT TRUE');
            }, 1000);

            const unsubscribe = lock.subscribe(async function run($lock) {
                if ($lock) {
                    return;
                }
                console.log('Done');
                clearInterval(updateInterval);
                unsubscribe();
            });

            return function cancel() {
                console.log('Canceled.');
            };
        }
    });
}

And the page is smth like that

// /routes/messages/+page.svelte
<script lang="ts">
    import type { PageData } from './$types';
    import { source } from 'sveltekit-sse';
    // ....

    const IS_BROWSER = typeof document !== 'undefined';

    const connection = source('/api/messages', {
        beacon: 60 * 1000,
        options: {
            timeout: 60 * 1000,
            headers: {
                'Access-Control-Allow-Origin': '*'
            }
        },
        close: (event) => {
            if (IS_BROWSER) {
                console.log('Connection closed', event.data);
                console.log('Reconnecting', event.error);
                event.connect();
            }
        },
        error: (event) => IS_BROWSER && console.error('Connection error', event.error)
    });

    const updatedMmessageString = connection.select('updated');

    export let data: PageData;

    let messages = data.messages;

    $: {
        if ($updatedMmessageString) {
            const rawMmessage = JSON.parse($updatedMmessageString);
            if (messages.find((t) => +t.id === +rawMmessage.id))
                messages = messages.map((t) => (+t.id === +rawMmessage.id ? rawMmessage : t));
            else messages.splice(0, 0, rawMmessage);
        }
    }
</script>
razshare commented 8 months ago

Hi @CyberNinja2007 ,

I'm trying to reproduce your issue but I don't see any errors on my side.

Here's the repo https://github.com/tncrazvan/sveltekit-sse-issue-29 I'm simulating some of your external calls with a 1 second delay.

If that doesn't clarify things, I'm not sure how else I could help you unfortunately, I would need a whole docker with a full example of what's going on, or at least more information on how to reproduce the issue.

razshare commented 8 months ago

Closing due to inactivity.