testing file uploads w/ websockets
yarn
node server
then open index.html
in yr browser
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="utf-8"> | |
<meta http-equiv="X-UA-Compatible" content="IE=edge"> | |
<meta name="viewport" content="width=device-width, initial-scale=1"> | |
<style> | |
progress { display: block; } | |
progress:empty { display: none; } | |
</style> | |
</head> | |
<body> | |
<header></header> | |
<progress></progress> | |
<input type="file" accept="image/jpeg"> | |
<script> | |
var ws = new WebSocket('ws://127.0.0.1:8899') | |
var input = document.querySelector('input[type="file"]') | |
var progress = document.getElementsByTagName('progress')[0] | |
input.addEventListener('change', function (ev) { | |
ws.send(ev.target.files[0]) | |
}) | |
ws.addEventListener('message', function (msg) { | |
var data = msg.data | |
if (typeof data === 'string') | |
data = JSON.parse(data) | |
if (data.type === 'greeting') { | |
document.querySelector('header').innerHTML = '<h1>' + data.message + '</h1>' | |
} | |
if (data.type === 'update') { | |
progress.max = data.total | |
progress.value = data.current | |
} | |
}) | |
</script> | |
</body> | |
</html> | |
{ | |
"name": "ws-test-file-upload", | |
"version": "0.0.0", | |
"main": "server.js", | |
"dependencies": { | |
"throttle": "^1.0.3", | |
"through2": "^2.0.3", | |
"ws": "^1.1.1" | |
} | |
} |
const WebSocket = require('ws') | |
const fs = require('fs') | |
const Throttle = require('throttle') | |
const through = require('through2') | |
const server = new WebSocket.Server({port: 8899}) | |
let pool = 0 | |
server.on('connection', function (ws) { | |
pool++ | |
ws.send(JSON.stringify({ | |
type: 'greeting', | |
message: 'you\'re on live w/ tha websocketz' | |
})) | |
console.log('connection # %d', pool) | |
ws.on('message', function (data) { | |
const out = fs.createWriteStream(`./image-${Date.now()}.jpg`) | |
const rate = 1024 * 10 | |
const total = data.length | |
let current = 0 | |
const thru = through(function (c, e, next) { | |
current += c.length | |
ws.send(JSON.stringify({type: 'update', current, total})) | |
this.push(c) | |
next() | |
}) | |
out.on('end', function () { | |
ws.send(JSON.stringify({ | |
type: 'status', | |
message: 'complete', | |
})) | |
}) | |
const throttle = Throttle(rate) | |
throttle.pipe(thru).pipe(out) | |
throttle.write(data) | |
}) | |
ws.on('close', function () { | |
pool-- | |
console.log('closed!') | |
}) | |
}) |
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. | |
# yarn lockfile v1 | |
buffer-shims@^1.0.0: | |
version "1.0.0" | |
resolved "https://registry.yarnpkg.com/buffer-shims/-/buffer-shims-1.0.0.tgz#9978ce317388c649ad8793028c3477ef044a8b51" | |
core-util-is@~1.0.0: | |
version "1.0.2" | |
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" | |
debug@2: | |
version "2.6.0" | |
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.0.tgz#bc596bcabe7617f11d9fa15361eded5608b8499b" | |
dependencies: | |
ms "0.7.2" | |
inherits@~2.0.1: | |
version "2.0.3" | |
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" | |
isarray@~1.0.0: | |
version "1.0.0" | |
resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" | |
[email protected]: | |
version "0.7.2" | |
resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.2.tgz#ae25cf2512b3885a1d95d7f037868d8431124765" | |
options@>=0.0.5: | |
version "0.0.6" | |
resolved "https://registry.yarnpkg.com/options/-/options-0.0.6.tgz#ec22d312806bb53e731773e7cdaefcf1c643128f" | |
process-nextick-args@~1.0.6: | |
version "1.0.7" | |
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3" | |
"readable-stream@>= 0.3.0", readable-stream@^2.1.5: | |
version "2.2.2" | |
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.2.2.tgz#a9e6fec3c7dda85f8bb1b3ba7028604556fc825e" | |
dependencies: | |
buffer-shims "^1.0.0" | |
core-util-is "~1.0.0" | |
inherits "~2.0.1" | |
isarray "~1.0.0" | |
process-nextick-args "~1.0.6" | |
string_decoder "~0.10.x" | |
util-deprecate "~1.0.1" | |
"stream-parser@>= 0.0.2": | |
version "0.3.1" | |
resolved "https://registry.yarnpkg.com/stream-parser/-/stream-parser-0.3.1.tgz#1618548694420021a1182ff0af1911c129761773" | |
dependencies: | |
debug "2" | |
string_decoder@~0.10.x: | |
version "0.10.31" | |
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" | |
throttle@^1.0.3: | |
version "1.0.3" | |
resolved "https://registry.yarnpkg.com/throttle/-/throttle-1.0.3.tgz#8a32e4a15f1763d997948317c5ebe3ad8a41e4b7" | |
dependencies: | |
readable-stream ">= 0.3.0" | |
stream-parser ">= 0.0.2" | |
through2@^2.0.3: | |
version "2.0.3" | |
resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.3.tgz#0004569b37c7c74ba39c43f3ced78d1ad94140be" | |
dependencies: | |
readable-stream "^2.1.5" | |
xtend "~4.0.1" | |
[email protected]: | |
version "1.0.2" | |
resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.0.2.tgz#ace116ab557cd197386a4e88f4685378c8b2e4fa" | |
util-deprecate@~1.0.1: | |
version "1.0.2" | |
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" | |
ws@^1.1.1: | |
version "1.1.1" | |
resolved "https://registry.yarnpkg.com/ws/-/ws-1.1.1.tgz#082ddb6c641e85d4bb451f03d52f06eabdb1f018" | |
dependencies: | |
options ">=0.0.5" | |
ultron "1.0.x" | |
xtend@~4.0.1: | |
version "4.0.1" | |
resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" |