Socket.IO Server API
原文链接:https://github.com/socketio/socket.io/blob/master/docs/API.md
仅用于学习参考,欢迎指出翻译错误Q^Q
Server
require("socket.io")
暴露的接口。
new Server(httpServer[, options])
httpServer
(http.Server)服务器绑定的http协议options
(对象)path
(字符串):捕获的路径名称(/socket.io)serveClient
(布尔值):是否向提供客户端文件(true)adapter
(适配器):使用适配器。默认为socket.io自带的基于内存的Adapter
实例。详情见socket.io-adapterorigins
(字符串):允许的origins
(*)allowRequest
(函数):一个接收被给予握手协议或是升级请求作为第一参数的函数,它可以决定是否继续。第二个参数是一个回调函数,用于处理决定是否继续的信息:fn(err, success)
,这里的success
是一个布尔值,false意味着请求被拒绝了,err是错误代码。parser
(解析器):使用解析器。默认为socket.io自带的Parser
实例。详情见socket.io-parser
使用或不适用new
的不同写法:
var io = require("socket.io")();
//or
var Server = require("socket.io");
var io = new Server();
传给socket.io的选项总是会传递给已创建的engine.io服务器。详情参考engine.io options
除此之外的一些选项:
pingTimeout
(数字):在不考虑回应的包时连接关闭的时长毫秒数(60000)。pingInterval
(数字):发送ping间隔时间毫秒数(25000)。
以上两个参数会影响客户端知道服务器端不再可获得的延迟状况。例如:如果底层的TCP连接因为网络原因没有正常关闭,那么客户端得到disconnect
事件可能需要等待的时间为pingTimeout + pingInterval
毫秒。
transports
(数组):transports允许和(['polling', 'websocket']
)有连接。
**注意:**次序是很重要的。默认情况下:首先建立的是一个长轮询连接,然后才可能升级为WebSocket。用['websocket']
意味着即使WebSocket连接未能成功打开也不能回退。
new Server(port[, options])
port
(数字)监听的端口(一个新的http.Server会被创建)options
(对象)
看这里了解可选参数
new Server(options)
options
(对象)
看这里了解可选参数
server.sockets
- (命名空间)
默认的命名空间(/
)。
server.serveClient([value])
value
(布尔值)- Returns
Server|布尔值
如果value
是true
,那么连接的服务器(见Server#attach
)则可以传输客户端文件。默认为true
。在attach
被调用后这个方法会失去效果。如果没有传参这个方法将返回当前的值。
// pass a server and the `serverClient` option
var io = require('socket.io')(http, {serveClient: false});
// or pass no server and then you can call the method
var io = require('socket.io')();
io.serveClient(false);
io.attach(http);
server.path([value])
value
(字符串)- Returns
Server|字符串
设置engine.io
和静态文件被提供的路径。默认为/socket.io
。如果没有传递参数会返回当前值。
server.adapter([value])
value
(适配器)- Returns
Server|字符串
设置适配器的值。默认为socket.io自带的基于内存的Adapter
实例。见socket.io-adapter。如果没有传参该方法将返回当前值。
server.origins([value])
value
(字符串)- Returns
Server|字符串
设置允许的‘origins’值。默认情况下任何‘origins’都是允许的。如果没有传参该方法返回当前值。
server.origins(fn)
fn
(函数)- Returns
Server
这里的函数‘fn’带有两个参数origin: String
和callback(error, success)
。success
是一个指示‘origin’是否被允许的布尔值。
潜在弊端
- 在某些情况下,你不能确保
origin
的值不为*
- 由于每次请求都会导致这个函数的执行,所有建议让它尽快被调用执行
- 如果
socket.io
是和express
一起使用的,CORS头只会被来自socket.io
的请求所影响。Express
可以使用cors
server.attach(httpServer[, options])
httpServer
(http.server)要连接的http服务器options
(对象)
在httpServer
上用提供的options
(可选的)把Server
连接到一个engine.io的实例上。
server.attach(port[, options])
port
(数字)要监听的端口号options
(对象)
在一个新的http.server上用提供的options
(可选的)把Server
连接到一个engine.io的实例上。
server.listen(httpServer[, options])
和server.attach(httpServer[, options])相同
server.listen(port[, options])
和server.attach(port[, options])相同
server.bind(engine)
engine
(engine.Server)- Returns
Server
高级用法。把服务器绑到特定的engine.io Server
(或者兼容的API)实例。
server.onconnection(socket)
socket
(engine.Socket)- Returns
Server
高级用法。从接入的engine.io(或兼容的API)Socket
创建一个新的socket.io
客户端。
server.of(nsp)
nsp
(字符串)- Returns
命名空间
利用nsp
路径名标识符来初始化和检索命名空间。如果命名空间已经被初始化了则立即返回该命名空间。
server.close([callback])
callback
(函数)
关闭socket.io服务器。callback
参数是可选的,它会在所有连接关闭后调用。
var Server = require('socket.io');
var PORT = 3030;
var server = require('http').Server();
var io = Server(PORT);
io.close(); // close current server
server.listen(PORT); // PORT is free to use
io = Server(server);
server.engine.generated
重写默认的方法来创建自定义的socket id。
当把一个node请求(http.IncomingMessage
)作为第一个参数时函数会被调用。
io.engine.generateId = function (req) {
return "custom: id:" + custom_id++; //custom id must be unique
}
Namespace(命名空间)
代表一个在同一个用路径名(例如:/chat
)定义的作用域下连接的所有sockets。
客户端总是默认连接到/
。
namespace.name
- (字符串)
命名空间的标识符属性。
namespace.connected
- (对象)
所有连接到这个命名空间的的Socket
对象的hash表,索引为其id。
namespace.emit(eventName[, args])
eventName
(字符串)args
向所有连接的客户端发送事件。以下两种写法等价:
var io = require('socket.io')();
io.emit("an event sent to all connected clients"); // main namespace
var chat = io.of('/chat');
chat.emit("an event sent to all connected in chat namespace");
namespace.clients(callback)
- callback(函数)
获取所有连接到这个命名空间的客户端ID列表(如果适用可横跨所有节点)。
var io = require('socket.io')();
io.of('/chat').clients(function(error, clients) {
if(error) throw error;
console.log(clients); // => [PZDoMHjiu8PYfRiKAAAF, Anw2LatarvGVVXEIAAAD]
});
一个获取所有在命名空间某房间中客户端的例子:
var io = require('socket.io')();
io.of('/chat').in('general').clients(function(error, clients) {
if(error) throw error;
console.log(clients); // => [Anw2LatarvGVVXEIAAAD]
});
当利用广播时,默认所有客户端来自默认命名空间("/"):
var io = require('socket.io')();
io.clients(function (error, clients) {
if(error) throw error;
console.log(clients); // => [6em3d4TJP8Et9EMNAAAA, G5p55dHhGgUnLUctAAAB]
});
namespace.use(fn)
fn
(函数)
寄存器中间件,每个接入的Socket
都需要执行这个方法,并且可以接收socket和一个可选的用于在下一个寄存器中间件延迟执行的函数作为参数。
传递给中间件回调函数的错误会作为特殊的错误包发给客户端。
var io = require("socket.io")();
io.use(function(socket, next) {
next(new Error("Authentication error"));
});
Event:'connect'
socket
(Socket)socket和客户端连接
在客户端连接时触发。
Event:"connection"
和Event:"connect"
相同
Flag:"volatile"
给随后发送的事件设置一个标识表明如果客户端还没准备好接收消息则事件数据可能丢失(因为网网速慢或者其他问题,或者因为它们是通过长轮询连接的并且正处在一个请求-应答循环中)。
io.volatile.emit("an event", {some: "data"}); // the clients may or may not receive it
Flag:"local"
给一个随后发送的事件设置一个标识表明该事件数据只会广播到当前节点(当适用Redis adapter)。
io.local.emit("an event", {some: "data"});
Socket
一个Socket
是和浏览器客户端交互的基类。一个Socket
属于一个特定的Namespace
(默认为/
)且适用底层的Client
进行通信。
值得一提的是Socket
和实际的底层TCP/IPsocket
没有直接关系,它只是一个类的类名而已。
在每个Namespace
中,也可以定用于socket加入和离开的任意频道(叫做room
)。这提供了一个方便的方式来向一组Sockets
广播(见下方的socket#to
)。
Socket
类继承自EventEmitter。Socket
类重写了emit
方法,并且没有修改EventEmitter
中任何其他的方法。这里列出的所有方法同样都是EventEmitter
的方法(除了emit
之外),都由EventEmitter实现,这些文档都用于Eventmitter
应用。
socket.id
- (字符串)
来自客户端底层的该阶段独一无二的标识符。
socket.rooms
- (对象)
客户端所在房间的字符串标识符组成的散列表,索引为房间名。
socket.client
- (客户端)
底层客户端对象的一个引用。
socket.conn
- (engine.Socket)
底层客户端传输连接(engine.io Socket
对象)的一个引用。这允许访问I/O传输层,其仍然(主要)是TCP/IP socket的抽象。
socket.request
- (请求)
返回源自底层engine.io Client
的请求的一个引用。用于对请求头的访问,例如Cookie
或User-Agent
。
socket.use(fn)
寄存器中间件,每个接入的Socket
都需要执行这个方法,并且可以接收该包和一个可选的用于在下一个寄存器中间件延迟执行的函数作为参数。
传递给中间件回调函数的错误会作为特殊的错误包发给客户端。
var io = require("socket.io")();
io.on("connection", function(socket) {
socket.use(function(packet, next) {
if(packet.doge === true) return next();
next(new Error("not a doge error"));
});
});
socket.send([...args][,ack])
args
ack
(函数)- Returns
Socket
发送一个message
事件。见socket.emit(eventName[, ...args][, ack])
socket.emit(eventName[, ...args][,ack])
(重写后的EventEmitter.emit
)
eventName
(字符串)args
ack
(函数)- Returns
Socket
通过字符串名字辨别发送的给socket的事件。可以包含任意其他的参数。支持所有序列化的数据结构,包括Buffer
。
socket.emit("hello", "world");
socket.emit("with-binary", 1, "2", {3: "4", 5: new Buffer(6)});
ack
参数是可选的,它会在客户端应答时调用。
var io = require("socket.io")();
io.on("connection", function(client) {
client.emit("an event", {some: "data"});
client.emit("ferret", "tobi", function (data) {
console.log(data); // data will be "woot"
});
// the client code
// client.on("ferret", function (name, fn) {
// fn("woot");
// });
});
socket.on(eventName, callback)
(继承自EventEmitter
)
eventName
(字符串)callback
(函数)- Returns
Socket
给给定事件注册的新的处理程序。
socket.on("news", function (data) {
console.log(data);
});
socket.once(eventName, listener)
socket.removeListener(eventName, listener)
socket.removeAllListeners([eventName])
socket.eventNames()
继承自EventEmitter
(这里的方法不在这里赘述)。详情见Node.js文档的events
模块。
socket.join(room[, callback])
room
(字符串)callback
(函数)- Returns
socket
链接
把客户端添加到room
,err
签名可触发回调函数(如果有的话)。
io.on("connection", function(socket) {
socket.join("room237", function () {
console.log(socket.rooms); //[<socket.id>, "room 237"]
// broadcast to everyone in the room
io.to("room 237", "a new user has joined the room");
});
});
加入房间的机制是由已配置的Adapter
处理的(见上Server#adapter
),默认为socket.io-adapter
为了方便起见,每个socket会根据它的id自动的加入某个房间(见Socket#id
)。这使得向其他sockets广播消息变得容易:
io.on("connection", function (client) {
client.on("say to someone", function (id, msg)) {
// send a private message to the socket with the given id
client.broadcast.to(id),.emit("my message", msg);
}
});
socket.join(rooms[,callback])
- rooms(数组)
- callback(函数)
- Returns
socket
链接
把客户端加到房间列表中,err
签名会触发回调函数(如果有的话)
socket.leave(room[, callback])
room
(字符串)callback
(函数)- Returns
Socket
链接
从room
移除客户端,err
签名会触发回调函数(如果有的话)
断开连接时将自动离开房间
socket.to(room)
room
(字符串)- Returns
Socket
链接
为接下来的发送的事件设置标识符,该事件只会被广播到加入给定room
的客户端处。
如果想发送到多个房间,可以调用多次。
var io = require("socket.io")();
io.on("connection", function (client) {
// to one room
client.to("others").emit("an event", {some: "data"});
// to mutiple rooms
client.to("room1").to("room2").emit("hello");
});
socket.in(room)
和socket.to(room)
相同
socket.compress(vaule)
value
(布尔值)是否将以下的包压缩- Returns
socket
链接
给接下来发送的事件加上标识符,即事件数据在值为true
时会被压缩。在没有调用该方法是默认为true
。
socket.disconnect(close)
close
(布尔值)是否断开底层连接- Returns
socket
断开该客户端。如果关闭的值为true
,则断开底层连接。否则,只是断开命名空间。
Flag:"broadcast"
为接下来发送的事件设置标识符,该事件数据会广播至除了发送者之外的其他任何客户端。
var io = require("socket.io")();
io.on("connection", function (socket) {
// everyone gets it but the sender
socket.broadcast.emit("an event", {some: "data"});
});
flag: "volatile"
为接下来发送的事件设置一个标识符,表明如果客户端没准备好接收数据则接下来发送的数据可能丢失(由于网速过慢或其他问题,或者它们是通过长轮询机制连接且处于请求-应答循环的中间环节)。
var io = require("socket.io")();
io.on("connection", function(socket) {
// the client may or may not receive it
socket.volatile.emit("an event", {some: "data"});
});
Event:"disconnect"
reason
(字符串) 断开的原因(客户端或服务器端)
当客户端即将断开时触发(但还没离开)
这些时保留的事件(connect
, newListener
和removeListener
)不能用作事件名称。
Client
Client
类表示接入的传输(engine.io)连接。 一个Client
可以和很多复合的属于不同Namespace
的Socket
有关系。
client.conn
- (engine.Socket)
一个底层engine.io``socket
连接的引用。
client.request
- (Request)
对源于engine.io的连接的引用。用于获取请求头信息比如Cookie
或User-Agent
。