前面学习了下 Express 框架,大概有了个了解了,基于 node.js 服务器算是简单搭建了个,完成了各种中间件使用,路由功能,那么接下来就是通信这块了,包括监听文件或数据的变化,和事件的监听和处理了,接下来就用到 Socket.io 这个东西了,刚接触看名字 socket 用来服务器到客户端的通信没错了!!!
Socket.io
首先熟悉下该书的 socket 内容,主要包括,建立连接,监听服务,监听文件变化后刷新浏览器显示数据等等。
按照惯例,首先得安装
- 安装
`npm install socket.io --save`
-
引用
var socketIO = require( 'socket.io' );
-
监听服务器连接
var io = socketIO.listen( server );
这里的 server 即时 http 模块创建的服务器对象
var server = http.createServer( ... );
监听文件变化
文件处理器
npm install fs --save
引用
var fsHandler = require( 'fs' );
监听文件变化: fsHandler.watchFile
// 被监听的文件容器
var watchMap = {};
var setWatch = function ( file_type, url_path ) {
debug( 'set watch on file : ' + url_path );
if ( !watchMap[ url_path ] ) {
debug( 'watching file : ' + url_path );
fsHandler.watchFile(
// 第一个参数必须为相对路径,所以要去掉第一个 '/' 字符
url_path.slice( 1 ),
function ( current, previous ) {
// current: 当前最新文件
// previous: 前一次修改的文件
// 最后修改时间对比
if ( current.mtime !== previous.mtime ) {
// 通过 socket 发布文件变动事件,通知客户度
/*
file_type: 目标文件类型
url_path: 目标文件路径
*/
io.sockets.emit( file_type, url_path );
}
}
);
// 对当前文件打上tag
watchMap[ url_path ] = true;
}
};
上面是个简短的文件变动监听程序,下面来启动该程序,通过路由,触发监听
自定义路由来监听文件变动
app.use( function ( req, res, next ) {
if ( req.url.indexOf( '/js/' ) >= 0 ) {
// 监听 js/ 目录下的脚本文件,类型为:'script'
setWatch( req.url, 'script' );
} else if ( req.url.indexOf( '/css/' ) >= 0 ) {
// 监听 css/ 目录下的样式文件,类型为:'stylesheet'
setWatch( req.url, 'stylesheet' );
}
next();
} );
文件变动监听程序完整代码
// socket.js
var
http = require( 'http' ),
express = require( 'express' ),
fsHandler = require( 'fs' ),
socketIO = require( 'socket.io' ),
serveStatic = require( 'serve-static' ),
app = express(),
watchMap = {}, // 被监听的文件容器
server, io,
// 函数
setWatch
;
// 文件变动监听程序
setWatch = function ( file_type, url_path ) {
debug( 'set watch on file : ' + url_path );
if ( !watchMap[ url_path ] ) {
debug( 'watching file : ' + url_path );
fsHandler.watchFile(
// 第一个参数必须为相对路径,所以要去掉第一个 '/' 字符
url_path.slice( 1 ),
function ( current, previous ) {
// current: 当前最新文件
// previous: 前一次修改的文件
// 最后修改时间对比
if ( current.mtime !== previous.mtime ) {
// 通过 socket 发布文件变动事件,通知客户度
/*
file_type: 目标文件类型
url_path: 目标文件路径
*/
io.sockets.emit( file_type, url_path );
}
}
);
// 对当前文件打上tag
watchMap[ url_path ] = true;
}
};
// 自定义路由监听文件变动
app.use( function ( req, res, next ) {
if ( req.url.indexOf( '/js/' ) >= 0 ) {
// 监听 js/ 目录下的脚本文件,类型为:'script'
setWatch( req.url, 'script' );
} else if ( req.url.indexOf( '/css/' ) >= 0 ) {
// 监听 css/ 目录下的样式文件,类型为:'stylesheet'
setWatch( req.url, 'stylesheet' );
}
next();
} );
app.use( serveStatic( __dirname + '/' ) );
app.use( '/', function ( req, res ) {
res.redirect( '/socket.html' );
} );
server = http.createServer( app );
io = socketIO.listen( server );
server.listen( 3000, function () {
debug( 'Http server listen on port 3000.' );
} );
客户端部分代码,注册监听事件到服务器
// socket.html
// 在头部引入 /socket.io/socket.io.js
// 一开始还去找这个文件,文中说这个可以直接用,不明白为啥
<script src="/socket.io/socket.io.js"></script>
<script id="script_a" src="/js/data.js"></script>
<body>
// 启动使用 /js/data.js 中数据
$(function () {
$( 'body' ).html( message );
});
io.connect('http://localhost:3000').on( 'script', function ( path ) {
// 先删除原来的
$( '#script_a' ).remove();
$( 'head' ).append(
'<script id="script_a" src="'
+ path
+ '"></scr' + 'ipt>'
);
// 用最新的 data.js 文件内容更新 DOM
$( 'body' ).html( message );
});
</body>
// data.js
var message = 'hello world !';
通过上面的代码就可以实现一个简单的文件变动监听和刷新小程序
主要关键点:
- 文件处理中间件:
fs
; - 文件监听程序:
fs.watchFile
; - 启动监听程序,设置被监听的文件类型和文件路径;
- 被监听的文件路径需要是相对路径; 即:
/js/data.js
->js/data.js
- 客户端连接服务器,并绑定从服务器发出的文件变动事件;
服务器发送事件
io.sockets.emit( file_type, url_path );
客户端绑定事件
io.connect( host ).on( file_type, eventHandler );
on
绑定的事件,即第一个参数,就是 emit
发送的事件类型,即其第一个参数,如上的 file_type。
比如:
发送 hello
事件
io.sockets.emit( 'hello', path );
绑定 hello
事件
io.connect( host ).on( 'hello', handler );
总结
这里简单了熟悉了下,如何使用 socket.io
去监听文件变化,和事件的发送和监听,更详细的关于 socket.io
的部分会在单独学习的时候去记录。