大吉大利,今晚吃鸡!
- PUBG
时隔多日,终于再次拾起这个拖了很久的项目。并不是因为没时间,也不是因为这个项目对于我来说有多困难,就是一个字————懒。
此项目的后台,当然是选择node.js来实现。作为一个前端,node.js比起java、php简单多了。
node支持的webSocket
在npm中有很多支持webSocket的模块,包括socket.io、node-websocket、faye-websocket-node等等,都可以实现webSocket,但是能查到的资料最多的应该算是socket.io了。
可参考粉丝日志里面对每种模块的实现:http://blog.fens.me/nodejs-we…
本项目选用的当然是socket.io 资料多,易上手。
socket.io
socket.io 安装
npm install socket.io --save
安装在项目内,并且保存在你的package.json中。
如何使用
使用socket.io非常简单,只需如下两个文件
index.js
var app = require('http').createServer(handler) // 使用了node自带的http模块
var io = require('socket.io')(app);
var fs = require('fs'); // node自带的fs模块
app.listen(3000); // 监听3000端口
// 定义一个处理器,当访问localhost:3000时,执行此函数,返回index.html文件
function handler (req, res) {
fs.readFile(__dirname + '/index.html',
function (err, data) {
if (err) {
res.writeHead(500);
return res.end('Error loading index.html');
}
res.writeHead(200);
res.end(data);
});
}
// 监听socket连接
io.on('connection', function (socket) {
//向web端推送消息
socket.emit('news', { hello: 'world' });
//接收web端传递的消息
socket.on('my other event', function (data) {
console.log(data);
});
});
index.html
<!-- 可在node_modules/socket.io-client中获取此文件 -->
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io('http://localhost:3000'); // 创建webSocket连接
socket.on('news', function (data) { // 监听on
console.log(data);
socket.emit('my other event', { my: 'data' }); // 发送my other event
});
</script>
若想结合express或Koa框架使用,请参阅socket.io文档https://socket.io/docs/ 中文版: https://zhuanlan.zhihu.com/p/…
API
下面介绍一些socket.io常用的API,可分为服务端和客户端两部分
服务端
1.构造函数 Server
实例化一个socket.io对象,有两种写法:
const io = require('socket.io')();
// or
const Server = require('socket.io');
const io = new Server();
接收两个参数(httpServer,options)【需要绑定的服务器,配置项】,第一个例子中的var app = require('http').createServer(handler)
就是一个服务器。
2.connect和connection事件
io.on('connect', (socket) => {
// ...
});
io.on('connection', (socket) => {
// ...
});
当有一个来自客户端的连接时触发该事件,参数socket为连接的客户端的socket对象。
3.socket
上面提到的socket可看做一个和下行客户端沟通的桥梁。他属于一个特定的命名空间(默认为”/”)。
socket.id: 一个独一无二的会话标志,来自与下行客户端,在发送消息给指定的客户端的时候非常有用
//发送给指定的客户端
io.sockets.connected[socket.id].emit('err','user is exist');
socket.rooms: 遗传哈希字符串,用来标志当前客户端所在的房间号,通过房间名称建立索引。有了房间机制就可实现给同一组房间内的socket推送消息,(可用来实现群聊)
io.on('connection', (socket) => {
socket.join('room 237', () => {
let rooms = Objects.keys(socket.rooms);
console.log(rooms); // [ <socket.id>, 'room 237' ]
});
});
socket.use:注册中间件,当任何讯息流经该中间件时执行中间件中的内容,该中间件会接受参数,也可以判断是否阻断后续中间件的执行
io.on('connection', (socket) => {
socket.use((packet, next) => {
if (packet.doge === true) return next();
next(new Error('Not a doge error'));
});
});
socket.send: 发送一个message事件,接收要发送的内容和回调函数为参数
socket.send('hi', function(data) {
console.log(data);
});
// 客户端
socket.on('message', function(data) {
console.log(data);
})
socket.emit: 重写/强化 EventEmitter.emit方法,通过事件名来触发事件给指定的socket,任意多的参数都可被传入,支持所有可序列化的数据结构。
接收一下参数:
eventName (字符串)
args 所以可序列化的数据结构 包括buffer
ack (Function)
// 简单的例子
socket.emit('print', 'hello world');
socket.emit('ferret', 'tobi', (data) => {
console.log(data); // data will be 'woot'
});
socket.on: 为给定的事件注册一个新的事件处理器。
socket.on('news', (data) => {
console.log(data);
});
// with several arguments
socket.on('news', (arg1, arg2, arg3) => {
// ...
});
// or with acknowledgement
socket.on('news', (data, callback) => {
callback(0);
});
socket.join: 添加客户端到room房间内,并且执行可选择的回调函数。
io.on('connection', (socket) => {
socket.join('room 237', () => {
let rooms = Objects.keys(socket.rooms);
console.log(rooms); // [ <socket.id>, 'room 237' ]
io.to('room 237', 'a new user has joined the room'); // broadcast to everyone in the room
});
});
socket.leave:从指定的房间里移除客户端,并且可选择的执行一个异常回调函数,与当客户端的连接丢失后,会自动的将其从房间移除
socket.leave('room 237',(res)=>{
console.log(res)
})
socket.io中的namespace和room,可参考文章:http://blog.csdn.net/lijiecon…
以上就是常用的服务API,下面介绍客户端的socket.io
客户端
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io('http://localhost:3000'); // 创建webSocket连接
socket.on('news', function (data) { // 监听on
console.log(data);
socket.emit('my other event', { my: 'data' }); // 发送my other event
});
</script>
IO: 创建socket连接,还可指定命名空间
io('http://localhost/users');
// 则将会对http://localhost进行传输连接,并且http://Socket.IO连接将会对"/users"建立连接。
也可提供查询参数:
io('http://localhost/users?token=abc')
还可以使用多路复用、携带额外的请求头
详细文档可参考: https://socket.io/docs/client…
connect: 监听是否与服务器连接成功,接收回调函数
const socket = io('http://localhost');
socket.on('connect', () => {
console.log('conncet ok');
});
connect_error:接错误触发事件处理器
socket.on('connect_error', (error) => {
// ...
});
disconnect:丢失连接时触发时间处理器
socket.on('disconnect', (timeout) => {
// ...
});
reconnect: 成功的重连时触发时间处理器
socket.on('reconnect', (timeout) => {
// ...
});
Sokect
也是一个连接服务端的对象,在连接到服务器之后也会生成与服务端socket相同的id
const socket = io('http://localhost');
console.log(socket.id); // undefined
socket.on('connect', () => {
console.log(socket.id); // 'G5p5...'
});
socket.open()和socket.connect(): 手动打开socket,可用于在连接断开后重新连接
socket.on('disconnect', () => {
socket.open();
});
socket.emit: 向服务端发送,与服务端的emit用法相同
socket.emit('ferret', 'tobi', (data) => {
console.log(data); // data will be 'woot'
});
socket.on:注册一个新的响应服务器事件的事件处理器,与服务端的用法相同
socket.on('news', (data) => {
console.log(data);
});
socket.close()和socket.disconnect(): 手动关闭客户端对服务器的链接