单页WEB应用(七),WebServer Node.js 之 Socket.IO

时间:2022-01-10 05:40:14

前面学习了下 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 !';

通过上面的代码就可以实现一个简单的文件变动监听和刷新小程序

主要关键点:

  1. 文件处理中间件:fs
  2. 文件监听程序: fs.watchFile;
  3. 启动监听程序,设置被监听的文件类型和文件路径;
  4. 被监听的文件路径需要是相对路径; 即:/js/data.js -> js/data.js
  5. 客户端连接服务器,并绑定从服务器发出的文件变动事件;

服务器发送事件

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 的部分会在单独学习的时候去记录。