-
Notifications
You must be signed in to change notification settings - Fork 7
S.H.Ran edited this page Jun 4, 2015
·
7 revisions
这里用RocketEngine写了一个简单的服务器,你会发现很像Socket.IO是不是…:
var fs = require('fs'),
util = require('util'),
http = require('http'),
path = require('path');
var rocket = require('../../index.js'),
RocketServer = rocket.Server;
var handler = function (socket) {
// manual set the timeout to 10s
socket.setTimeout(0);
// test non-browser client connect
socket.on('terminal', function (data) {
console.log(data);
});
socket.on('closing', function (code) {
console.log(code);
//process.exit(0);
});
socket.on('disconnected', function (info) {
util.log('ws info: client id: ' + socket.id + ' offline');
console.log(info);
});
socket.receive(function (data) {
console.log(data);
});
socket.on('awake', function (d) { console.log(d); });
//util.log('ws info: client id: ' + socket.id + ' online');
// test non-browser client connect
socket.emit('hello', 'hi');
socket.emit('awake');
// press test
/*for (var i = 0; i < 1000000; i++)
socket.send('asd');*/
};
// test stream-style API
var handler_1 = function (socket) {
socket.setTimeout(0);
socket.on('lol', function (imgstream) {
imgstream.pipe(fs.createWriteStream('./dump.gif')).on('finish', function () {
socket.send(fs.createReadStream('./dump.gif'));
});
});
};
var handler_2 = function (socket) {
socket.setTimeout(0);
socket.close(1000, 'yeah, closed!');
};
// statics list
var statics = {
'/': './ws2.html',
'/chat': './ws.html',
'/testclose': './ws3.html'
};
statics.__proto__ = null;
// http server
var httpServer = http.createServer(function(req, res) {
if (req.url in statics) {
fs.readFile(path.join(__dirname, statics[req.url]), function (err, file) {
res.end(file);
});
} else {
res.statusCode = 404;
res.statusMessage = 'Not Found';
res.end('NOT FOUND');
}
});
// websocket server with three different namespaces
// => /, /chat, /testclose
var rock = new RocketServer(httpServer).on('connected', handler)
, rock_1 = new RocketServer(httpServer, {
namespace: '/chat'
}).on('connected', handler_1)
, rock_2 = new RocketServer(httpServer, {
namespace: '/testclose'
}).on('connected', handler_2);
// listen on websocket request
rocket.listen(httpServer, function(httpServer){
util.log('wsf server start');
console.log('open localhost:3000/testclose and localhost:3000/chat to see what happened~');
// start the http server
httpServer.listen(3000);
});
对应浏览器中的代码是这样的:
// ws.html
<html>
<body>
<img id="ws">
<input type="file" id='upload'/>
<script src="/event.js"></script>
<script src="/rocken.js"></script>
<script>
/* reference usage */
var url = location.href.split('://')[1];
rocken.connect('ws://' + url, function (socket) {
// in default setting, 'reconnect' is enabled
// invoke socket.autoreconnect = false to disabled
console.log('connected');
// set reconnect no-delay
socket.expire = 0;
socket.on('close', function (info) {
console.log('bye', info);
});
var upload = document.querySelector('#upload');
upload.addEventListener('change', function (e) {
var file = e.target.files[0];
socket.emit('lol', file);
});
socket.receive(function (data) {
bloburl = URL.createObjectURL(data);
document.querySelector('#ws').src = bloburl;
});
});
</script>
</body>
</html>
// ws2.html
<html>
<body>
<img id="ws">
<script src="/event.js"></script>
<script src="/rocken.js"></script>
<script>
/* reference usage */
var url = location.href.split('://')[1];
ws=rocken.connect('ws://' + url, function (socket) {
// in default setting, 'reconnect' is enabled
// invoke socket.autoreconnect = false to disabled
console.log('connected');
// set reconnect no-delay
socket.expire = 0;
socket.on('close', function (info) {
console.log('bye', info);
});
socket.on('awake', function (d) {
console.log(d);
socket.emit('awake');
});
socket.receive(function (data) {
console.log(data);
socket.send(data);
});
});
</script>
</body>
</html>
// ws3.html
<html>
<body>
<img id="ws">
<script src="/event.js"></script>
<script src="/rocken.js"></script>
<script>
/* reference usage */
var url = location.href.split('://')[1];
ws=rocken.connect('ws://' + url, function (socket) {
// set reconnect no-delay
socket.autoreconnect = false;
// normal close
//socket.close(1000);
socket.on('close', function (info) {
console.log(info);
});
});
</script>
</body>
</html>
用作non-browser的客户端:
var wsf = require('../index.js');
wsf.connect('ws://127.0.0.1:3000', function(client) {
client.on('hello', function (data) {
console.log(data);
client.emit('terminal', 'hello');
client.close();
});
});
RocketEngine也可以很好的整合进express,这个例子展示的是一个实时文件系统浏览器:
Note:以下例子中使用的express为4.x版本!
// file: app.js
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var routes = require('./routes');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
// uncomment after placing your favicon in /public
//app.use(favicon(__dirname + '/public/favicon.ico'));
app.use(logger('dev'));
app.use(express.static(path.join(__dirname, 'public')));
app.use(routes);
module.exports = app;
// file: routes/index.js
var express = require('express');
var router = express.Router();
var wsf = require('fslider_ws');
/* GET home page. */
router.get('/', function (req, res, next) {
res.render('index');
});
module.exports = router;
// file: bin/www
var debug = require('debug')('watcher');
var app = require('../app');
app.set('port', process.env.PORT || 3000);
var fs = require('fs');
var http = require('http');
var wsf = require('fslider_ws');
var WServer = wsf.Server;
var server = http.createServer(app);
var ws = new WServer(server);
ws.on('connected', function (socket) {
socket.setTimeout(0);
// recommend configure the fragmentSize, or it will go crazy!
// configuration depends on OS kernel/userspace's buffer size
// default to 2^10 (1KB), max is 2^32 (4GB)
socket.fragmentSize = 0x400; // 1KB
var watcher = null;
socket.on('read', function (d) {
fs.stat(d, function (err, stat) {
if (err)
return socket.emit('err', err.code);
watcher && fs.unwatchFile(d);
if (stat.isDirectory()) {
var dir = fs.readdirSync(d);
watcher = fs.watchFile(d, function (e, f) {
socket.send(fs.readdirSync(d));
});
socket.send(dir);
} else if (stat.isFile()) {
var file = fs.readFileSync(d);
watcher = fs.watchFile(d, function (e, f) {
socket.send(fs.readFileSync(d));
});
socket.send(file);
}
});
});
});
wsf.listen(server);
server.listen(app.get('port'));
浏览器部分:
<!DOCTYPE html>
<html>
<body>
<input type="text" id='path'>
<ul id='panel'></ul>
<script src='/javascripts/event.js'></script>
<script src='/javascripts/wsf.js'></script>
<script type="text/javascript">
var path = document.querySelector('#path');
var panel = document.querySelector('#panel');
function flush(d) {
panel.innerHTML = '';
if (Array.isArray(d)) {
var df = document.createDocumentFragment();
d.forEach(function (e, i) {
var li = document.createElement('li');
li.innerHTML = e;
df.appendChild(li);
});
panel.appendChild(df);
} else if (d instanceof Blob) {
var url = URL.createObjectURL(d);
panel.innerHTML='<li><img src="'+url+'"></li>'
} else {
panel.innerHTML = '<pre>' + d + '</pre>';
}
}
wsf.connect('ws://ran:3000', function (socket) {
socket.recive(flush);
socket.on('err', function (d) {
panel.innerHTML = d;
});
path.addEventListener('input', function (e) {
socket.emit('read', path.value.trim());
});
});
</script>
</body>
</html>
- 中文版Wiki首页
- Server参考手册
- Browser参考手册
- [Non-Browser参考手册](https://github.com/abbshr/RocketEngine/wiki/Non Browser客户端参考手册)
- 诞生缘由
- 示例