Good morning all,
I am experimenting with Deno and Oak framework. I want to do a WebSocket connection between the front-end and the back-end. I know how to do it using the Deno standard library ('HTTP') but when trying to use Oak, I keep running into errors.
My current code is:
import { Application, Router } from "https://deno.land/x/[email protected]/mod.ts";
import { WebSocket, acceptWebSocket, isWebSocketCloseEvent, acceptable } from 'https://deno.land/[email protected]/ws/mod.ts';
import { staticFileMiddleware } from './staticFileMiddleware.ts';
const app = new Application();
const router = new Router();
router
.get('/', (ctx) => {
ctx.response.redirect('/index.html');
})
.get('/ws', async (ctx: any) => {
// console.log(ctx.request.serverRequest);
const sock = await ctx.upgrade();
let id = socks.push(sock) - 1;
for await (const ev of sock);
socks.splice(id, 1);
if (acceptable(ctx.request.serverRequest)) {
const { conn, r: bufReader, h: bufWriter, headers } = ctx.request.serverRequest;
const socket = await acceptWebSocket({
conn,
bufReader,
bufWriter,
headers
});
await chat(socket);
} else {
throw new Error('Error when connecting websocket');
}
});
app.use(router.routes());
app.use(router.allowedMethods());
app.use(staticFileMiddleware);
app.addEventListener('listen', ({hostname, port, secure}) => {
console.log(`Listening on ${secure ? 'https://' : 'http://'}${hostname || 'localhost'}:${port}`)
});
app.addEventListener('error', e => {
console.log(e.error);
});
await app.listen({ port: 3000 });
async function chat(ws: WebSocket) {
console.log(`Connected`);
for await (let data of ws) {
console.log(data, typeof data);
ws.send('Your message was successfully received');
if (isWebSocketCloseEvent(data)) {
console.log('Goodbye');
break;
}
}
}
My static file middleware is:
import { Context, send } from "https://deno.land/x/[email protected]/mod.ts";
export const staticFileMiddleware = async (ctx: Context, next: Function) => {
const path = `${Deno.cwd()}/public${ctx.request.url.pathname}`;
if (await fileExists(path)) {
await send(ctx, ctx.request.url.pathname, {
root: `${Deno.cwd()}/public`
})
} else {
await next();
}
}
async function fileExists(path: string) {
try {
const stats = await Deno.lstat(path);
return stats && stats.isFile;
} catch (e) {
if (e && e instanceof Deno.errors.NotFound) {
return false;
} else {
throw e;
}
}
}
The client-side code includes:
let ws;
window.addEventListener('DOMContentLoaded', () => {
ws = new WebSocket(`ws://localhost:3000/ws`);
ws.addEventListener('open', onConnectionOpen);
ws.addEventListener('message', onMessageReceived);
});
function onConnectionOpen() {
console.log('Connection Opened');
ws.send('I am sending a message from the client side');
}
function onMessageReceived(event) {
console.log('Message Received', event);
}
My file structure is as follow:
server.ts
staticFileMiddleware.ts
/public
-client.js
-index.html
I would greatly appreciate it if you could help me and point me into the right direction. Thank you in advance for your help!!!
I have copied above code and tried to run, i was getting error in
sock.push()
blockSo removed that unnecesory code. of
server.ts
While destructing the
ctx.request.serverRequest
i see there ish:bufWriter
is undefined there and throwing the error like,Here is the updated code,