Skip to content

Instantly share code, notes, and snippets.

@jimmont
Created July 27, 2020 00:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jimmont/b00e24f479b9c955092e778c33c7a163 to your computer and use it in GitHub Desktop.
Save jimmont/b00e24f479b9c955092e778c33c7a163 to your computer and use it in GitHub Desktop.
http upgrade websocket
/*
running with Deno 1.2
deno run --inspect --allow-net ./websockets.js
*/
import { Application, Router, HttpError, send, Status } from "https://deno.land/x/oak@v6.0.1/mod.ts";
import { isWebSocketCloseEvent } from "https://deno.land/std@0.61.0/ws/mod.ts";
const port = 8123;
const users = new Set();
const app = new Application({state:{users}});
const router = new Router();
function broadcastEach(user){
user.send(this);
}
function broadcast(msg){
console.log('---broadcasting--->', typeof msg, msg);
users.forEach(broadcastEach, msg);
}
router.get('/socket', async (context, next) => {
if( !context.isUpgradable ){
throw new Error('bummers opening socket :(');
}
const socket = await context.upgrade();
users.add(socket);
broadcast(`hello! ${ socket.conn.rid }`);
for await (const ev of socket) {
if(isWebSocketCloseEvent(ev)){
users.delete(socket);
broadcast(`bye! ${ socket.conn.rid }`);
}else{
broadcast(ev);
};
}
});
router.get('/', async (context) => {
context.response.body = `<!doctype html>
<html><body>
<p>let's chat...open the console to chat it up</p>
<script>
console.log(123);
const pipe = new WebSocket("ws://${context.request.url.host}/socket");
function fire(ev){
switch(ev.type){
case 'message':
switch(typeof ev.data){
case 'string':
console.log('msg text', ev.data);
break;
case 'object':
ev.data.arrayBuffer().then(ab=>{ console.log(new Uint8Array(ab)); });
break;
}
break;
default:
console.log(ev.type ,ev);
}
}
function hello(msg){
if(msg === undefined){
msg = new ArrayBuffer(4);
const uint = new Uint8Array(msg);
uint[0] = 4;
uint[1] = 3;
uint[2] = 2;
uint[3] = 1;
}
pipe.send(msg);
}
pipe.addEventListener('open', fire);
pipe.addEventListener('close', fire);
pipe.addEventListener('message', fire);
pipe.addEventListener('error', fire);
</script>
</body></html>
`;
});
app.use(router.routes());
app.use(router.allowedMethods());
app.addEventListener('error', (ev)=>{
console.error(ev);
debugger;
});
app.addEventListener('listen', (server)=>{
console.log(`open ${ server.secure ? 'https':'http' }://${ server.hostname }:${ server.port }`);
});
const whenClosed = app.listen(`:${port}`);
await whenClosed;
console.log(`closed http :${port}, bye`);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment