node/socket.io搭建聊天室

今天看了《nodejs实战》第二章,构建聊天程序,对node练了练手,趁热打铁,将看过的东西记录下来。

涉及模块

  • http 模块用来创建http服务
  • fs 用来处理静态文件
  • path 文件系统路径相关
  • mime 根据文件的扩展名,得到文件类型, 如:text/html
  • socket.io socket模块

思路

1.创建文件服务器
  1. http创建服务器,处理请求,获取请求路径
  2. 首先在缓存中读取,若无缓存,通过fs读取对应的html文件并转发
  3. http监听端口
2.创建socket通信
  1. 通过socket.io进行连接,包括客户端和服务端两部分
  2. 连接成功为用户分配id,名称,并绑定消息事件
  3. 客户端与服务端通过emit,on进行事件的监听与触发,进行交互

总结

整体思路清晰简单,因为有socket.io 客户端及服务端的封装,整体通过事件进行交互很简单明了。下面对这几个模块的常用API进行总结

HTTP

直接使用

  • http.STATUS_CODES 状态码
  • http.createServer
  • http.request(http.ClientRequest)
  • http.get
  • http.globalAgent
  • http.IcomingMessage

回调参数

  1. http.serverRequest
  2. http.serverResponse
  3. http.Agent

点击看这篇文章,里面讲解的很详细

fs文件系统

常规操作

1
2
3
4
5
6
fs.open(文件路径,读写标识,[文件mode值,666],回调函数(err,文件句柄fd));
fs.read(文件句柄fd,被写入的buffer,offset,length,position,回调函数(err, bytesRead, buffer));
fs.write(文件句柄fd,被读取的buffer,offset,length,position,回调函数(err,bytesWritten,buffer));
fs.close(文件句柄,回调函数)
fs.truncate(文件句柄,截断长度,回调函数);
fs.fsync(文件句柄,回调函数);

文件读写

1
2
3
fs.readFile(文件名,编码,回调函数(err,data));
fs.writeFile(文件名,数据,编码,回调函数(err));
fs.appendFile(文件名,数据,编码,回调函数(err));

目录操作

1
2
3
fs.mkdir(路径,权限mode/777,回调函数);
fs.rmdir(路径,回调函数);
fs.readdir(路径,回调函数(err,fileNameArray));

其他常用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//判断文件是否存在
fs.exists(文件路径,callback(是否存在));
//重命名
fs.rename(旧文件名,新文件名,回调函数);
//文件所有者变更
fs.chown(文件名,uid,gid,回调函数);/fs.fchown(文件句柄fd,uid,gid,回调函数);/fs.lchown(链接路径,uid,gid,回调函数);
//文件权限变更
fs.chmod(文件名,mode,回调函数);/fs.fchmod(文件句柄,mode,回调函数);/fs.lchmod(链接路径,mode,回调函数);
//文件信息
fs.stat(文件路径,回调函数(err.fs.Stats对象));/fs.fstat(文件句柄fd,回调函数(err.fs.Stats对象));/fs.lstat(链接路径,回调函数(err.fs.Stats对象));
//文件时间
fs.utimes(文件路径,访问时间,新建时间,回调函数);/fs.futimes(文件句柄,访问时间,新建时间,回调函数);
//监视文件
fs.watchFile(文件名,[options],listener_callback(当前文件的stats,改变前的stats));
fs.unwatchFile(文件名);

path

路径操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
//格式化路径. 将不符合规范的路径经过格式化转换为标准路径,解析路径中的.与…外,还能去掉多余的斜杠
//=> /path/normalize/
path.normalize(’/path///normalize/hi/…’)
//组合路径
//=>‘/you/are/beautiful’
path.join(’///you’, ‘/are’, ‘//beautiful’);
//返回路径中的目录名
path.dirname(’/foo/strong/cool/nice’);
//=> ‘/foo/strong/cool’
//返回路径最后一部分,还可以排除指定字符串
path.basename(’/foo/strong/basename/index.html’);
path.basename(’/foo/strong/basename/index.html’,’.html’);
//=> index.html 和 index
//返回路径后缀
path.extname(‘index.html’);
=>.html
//返回绝对路径
path.resolve([from …], to)
path.resolve('wwwroot', 'static_files/png/', '../gif/image.gif')
// 如果当前工作目录为 /home/myself/node,它返回:
'/home/myself/node/wwwroot/static_files/gif/image.gif'
//返回从from到to的相对路径
path.relative(from, to)

socket.io

配合socket.io模块,可以很简单的进行websocket通信,具体使用方法如下:
二者通过事件进行消息传递,简单好用。

1.服务端

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//1.获取socketio
var io = require('socket.io')(server);
//2.用户连接时注册事件
io.sockets.on('connection', function(socket) {
//广播
socket.broadcast.to(room).emit('message',{
text: '广播信息'
})
//接收信息
socket.on('message', function(message) {
console.log(message.message);
})
//向客户端传递消息
socket.emit('message', {msg: 'aaa'})
});

2.客户端

1
2
3
4
5
6
7
8
//1.建立连接
var socket = io.connect('http://localhost:3000');
//2.监听事件
socket.on('event', function(result) {...});
//3.触发事件
socket.emit('message', message);