cmorten / opine

Minimalist web framework for Deno ported from ExpressJS.
https://github.com/cmorten/opine/blob/main/.github/API/api.md
MIT License
854 stars 43 forks source link

Websocket connection keep (pending) #130

Closed 4ov closed 3 years ago

4ov commented 3 years ago

Issue

Setup:

Details

I'm trying to attach websocket to opine server sample code:

import { opine, serveStatic } from 'https://deno.land/x/opine@1.4.0/mod.ts'
import {
    acceptWebSocket,
    isWebSocketCloseEvent,
    isWebSocketPingEvent,
    WebSocket,
} from "https://deno.land/std@0.99.0/ws/mod.ts";
const app = opine()
//this part of code from https://deno.land/std/ws example
async function handleWs(sock: WebSocket) {
    console.log("socket connected!");
    try {
        for await (const ev of sock) {
            if (typeof ev === "string") {
                // text message.
                console.log("ws:Text", ev);
                await sock.send(ev);
            } else if (ev instanceof Uint8Array) {
                // binary message.
                console.log("ws:Binary", ev);
            } else if (isWebSocketPingEvent(ev)) {
                const [, body] = ev;
                // ping.
                console.log("ws:Ping", body);
            } else if (isWebSocketCloseEvent(ev)) {
                // close.
                const { code, reason } = ev;
                console.log("ws:Close", code, reason);
            }
        }
    } catch (err) {
        console.error(`failed to receive frame: ${err}`);

        if (!sock.isClosed) {
            await sock.close(1000).catch(console.error);
        }
    }
}

app.all('/ws', async (req, res, next) => {
    const { conn, r: bufReader, w: bufWriter, headers } = req;
    await acceptWebSocket({
        conn,
        bufReader,
        bufWriter,
        headers
    }).then(d=>{
     d.send('hola') 
    })
})

app.listen(3000)

i hope you help me in this problem and/or give an example for using websockets

cmorten commented 3 years ago

Hi @4ov 👋

One gotcha I have found with ws is that the versions of the std lib for http and ws typically have to match exactly otherwise you experience hanging connections and/or errors.

Latest Opine is currently using std@0.97.0 ( https://github.com/asos-craigmorten/opine/blob/main/deps.ts#L6 ). Please try using this version for your ws import and see if issues are resolved.

Unfortunately this is not something that can be solved in Opine itself as it arises due to clashes between minor versions of the std lib itself.

Another workaround is to use importmaps to override the std lib version which Opine uses to match your preference.

As for an example, we can look to add one to this repo. In the meantime I have a working use of ws with Opine in https://github.com/cmorten/luath/blob/main/src/middlewares/lmr/mod.ts#L161 ( a Deno tool for HMR development ) which can serve as a guide, though perhaps a slightly more embedded and complex example!

4ov commented 3 years ago

Working, Thanks for helping i really appreciate it.