socket.io 服务端API

2018-10-18 11:06 更新

服务端 | Server


Exposed byrequire('socket.io')

新服务器 (httpServer[, options])

  • httpServer (http.Server)要绑定的服务器。
  • options (目的)
    • path (String):捕获路径的名称(/socket.io
    • serveClient (Boolean):是否提供客户端文件(true
    • adapter (适配器):适配器使用。默认为Adapter 与基于内存的socket.io附带的实例请参阅 socket.io-adapter
    • origins (String):允许的originins(*
    • parser (Parser):解析器使用。默认为Parser socket.io附带的实例请参阅 socket.io-parser

有和没有工作new:

const io = require('socket.io')();
// or
const Server = require('socket.io');
const io = new Server();

传递给socket.io的相同选项始终传递给engine.io Server创建的选项。请参阅engine.io 选项作为参考。

其中:

  • pingTimeout (Number):有多少ms没有乒乓包考虑连接close(60000)
  • pingInterval (Number):发送新的ping packet(25000)之前有多少ms 。

这两个参数将在客户端知道服务器不再可用之前影响延迟。例如,如果底层TCP连接由于网络问题而未正确关闭,则pingTimeout + pingInterval在获取disconnect事件之前,客户端可能必须等待最多ms 。

  • transports (Array <String>):传输以允许连接到(['polling', 'websocket'])。

注意:顺序很重要。默认情况下,首先建立长轮询连接,然后如果可能,升级到WebSocket。使用['websocket']方法如果无法打开WebSocket连接,则不会有后备。

const server = require('http').createServer();

const io = require('socket.io')(server, {
  path: '/test',
  serveClient: false,
  // below are engine.IO options
  pingInterval: 10000,
  pingTimeout: 5000,
  cookie: false
});

server.listen(3000);

Server(port [,options])

  • port (数字)一个要听的端口(一个新的http.Server将被创建)
  • options (目的)

请参阅上面的可用选项。

const server = require('http').createServer();

const io = require('socket.io')(3000, {
  path: '/test',
  serveClient: false,
  // below are engine.IO options
  pingInterval: 10000,
  pingTimeout: 5000,
  cookie: false
});

新服务器(选项)

  • options (目的)

请参阅上面的可用选项。

const io = require('socket.io')({
  path: '/test',
  serveClient: false,
});

// either
const server = require('http').createServer();

io.attach(server, {
  pingInterval: 10000,
  pingTimeout: 5000,
  cookie: false
});

server.listen(3000);

// or
io.attach(3000, {
  pingInterval: 10000,
  pingTimeout: 5000,
  cookie: false
});

server.sockets

  • (命名空间)

default(/)命名空间。

server.serveClient([value])

  • value (布尔)
  • 返回 Server|Boolean

如果value是true连接的服务器(请参阅Server#attach)将担任客户端文件。默认为true。此方法attach调用后无效。如果没有提供参数,则此方法返回当前值。

// pass a server and the `serveClient` option
const io = require('socket.io')(http, { serveClient: false });

// or pass no server and then you can call the method
const io = require('socket.io')();
io.serveClient(false);
io.attach(http);

server.path([value])

  • value (串)
  • 返回 Server|String

设置的路径value下,其engine.io与静态文件将送达。默认为/socket.io。如果没有提供参数,则此方法返回当前值。

const io = require('socket.io')();
io.path('/myownpath');

// client-side
const socket = io({
  path: '/myownpath'
});

server.adapter([value])

  • value (适配器)
  • 返回 Server|Adapter

设置适配器value。默认为Adapter与基于内存的socket.io附带的实例。请参阅socket.io-adapter。如果没有提供参数,则此方法返回当前值。

const io = require('socket.io')(3000);
const redis = require('socket.io-redis');
io.adapter(redis({ host: 'localhost', port: 6379 }));

server.origins([value])

  • value (串)
  • 返回 Server|String

设置允许的来源value。默认为允许的任何来源。如果没有提供参数,则此方法返回当前值。

io.origins(['foo.example.com:443']);

server.origins(fn)

  • fn (功能)
  • 返回 Server

提供了一个函数取两个参数origin:String和callback(error, success),其中success是说明产地,是否允许或不允许一个布尔值。

潜在缺点:

  • 在某些情况下,如果不可能确定origin它可能有价值*
  • 由于此功能将针对每个请求执行,建议使该功能尽可能快地工作
  • 如果socket.io与之一起使用Express,则CORS头将仅受到socket.io请求的影响。快递可以使用cors
io.origins((origin, callback) => {
  if (origin !== 'https://foo.example.com') {
    return callback('origin not allowed', false);
  }
  callback(null, true);
});

server.attach(httpServer [,options])

  • httpServer (http.Server)要附加的服务器
  • options (目的)

使用提供的(可选)附加Server到engine.io实例。httpServeroptions

server.attach(port [,options])

  • port (Number)要侦听的端口
  • options (目的)

Server使用提供的options(可选)将新的http.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)
  • 返回 Server

仅限高级使用。将服务器绑定到特定的engine.io Server(或兼容API)实例。

server.onconnection(socket)

  • socket (engine.Socket)
  • 返回 Server

仅限高级使用。socket.io从传入的engine.io(或兼容的API)创建一个新的客户端Socket。

server.of(nsp)

  • nsp (串)
  • 返回 Namespace

Namespace通过其路径名标识符初始化并检索给定的nsp。如果命名空间已经被初始化,它会立即返回。

const adminNamespace = io.of('/admin');

server.close([callback])

  • callback (功能)

关闭socket.io服务器。该callback参数是可选的,在关闭所有连接将被调用。

const Server = require('socket.io');
const PORT   = 3030;
const server = require('http').Server();

const io = Server(PORT);

io.close(); // Close current server

server.listen(PORT); // PORT is free to use

io = Server(server);

server.engine.generateId

覆盖默认方法以生成您的自定义套接字ID。

该函数以节点请求object(http.IncomingMessage)作为第一个参数被调用。

io.engine.generateId = (req) => {
  return "custom:id:" + custom_id++; // custom id must be unique
}

#命名空间

表示在由路径名(例如:)标识的给定范围内连接的套接字池/chat。

客户端始终连接到/(主命名空间),然后可能连接到其他命名空间(使用相同的底层连接)。

namespace.name

  • (串)

命名空间标识符属性。

namespace.connected

  • (对象<插座>)

Socket连接到此命名空间的对象的哈希,由索引编号id。

namespace.adapter

  • (适配器)

该Adapter用于命名空间。在使用Adapter基于Redis的时候很有用,因为它暴露了管理集群中的套接字和房间的方法。

注意:可以访问主命名空间的适配器io.of('/').adapter。

namespace.to(room)

  • room (串)
  • Namespace链接返回

为随后的事件发射设置一个修饰符,事件只会广播到已经加入给定的客户端room。

要发射到多个房间,可以to多次打电话。

const io = require('socket.io')();
const adminNamespace = io.of('/admin');

adminNamespace.to('level1').emit('an event', { some: 'data' });

namespace.in(room)

namespace.to(room)的同义词。

namespace.emit(eventName [,... args])

  • eventName (串)
  • args

向所有连接的客户端发出事件。以下两个是等效的:

const io = require('socket.io')();
io.emit('an event sent to all connected clients'); // main namespace

const chat = io.of('/chat');
chat.emit('an event sent to all connected clients in chat namespace');

注意:从命名空间发布时,不支持确认。

namespace.clients(callback)

  • callback (功能)

获取连接到此命名空间的客户机ID(跨所有节点(如果适用))。

const io = require('socket.io')();
io.of('/chat').clients((error, clients) => {
  if (error) throw error;
  console.log(clients); // => [PZDoMHjiu8PYfRiKAAAF, Anw2LatarvGVVXEIAAAD]
});

获取命名空间中所有客户端的一个示例:

io.of('/chat').in('general').clients((error, clients) => {
  if (error) throw error;
  console.log(clients); // => [Anw2LatarvGVVXEIAAAD]
});

与广播一样,默认是默认命名空间('/')的所有客户端:

io.clients((error, clients) => {
  if (error) throw error;
  console.log(clients); // => [6em3d4TJP8Et9EMNAAAA, G5p55dHhGgUnLUctAAAB]
});

namespace.use(fn)

  • fn (功能)

注册一个中间件,这是一个为每个传入执行的功能Socket,并且接收套接字和可选地将执行延迟到下一个注册的中间件的参数。

传递给中间件回调的错误作为特殊error数据包发送给客户端。

io.use((socket, next) => {
  if (socket.request.headers.cookie) return next();
  next(new Error('Authentication error'));
});

事件:'连接'

  • socket (Socket)与客户端的套接字连接

在客户端连接时被触发。

io.on('connect', (socket) => {
  // ...
});

io.of('/admin').on('connect', (socket) => {
  // ...
});

事件:'连接'

事件的同义词:'connect'

旗:'volatile'

为后续事件发射设置修改器,如果客户端未准备好接收消息(因为网络缓慢或其他问题,或者因为通过长轮询连接并且处于请求中间),则事件数据可能丢失响应周期)。

io.volatile.emit('an event', { some: 'data' }); // the clients may or may not receive it

旗:'本地'

为随后的事件发射设置修改器,事件数据将仅广播到当前节点(使用Redis适配器时)。

io.local.emit('an event', { some: 'data' });

#插座

A Socket是与浏览器客户端进行交互的基本类。A Socket属于某个Namespace(默认情况下/),并使用底层Client进行通信。

应该注意的Socket不直接与实际的底层TCP / IP有关socket,它只是该类的名称。

在每个内部Namespace,您还可以定义可以加入和离开的任意通道(称为room)Socket。这提供了一种方便的方式来广播到一组Socket(见Socket#to下文)。

在Socket类继承自EventEmitter。本Socket类覆盖了emit方法,并且不修改任何其他EventEmitter方法。所有在这里记录的方法也可以作为EventEmitter方法(除了以外emit)由...实现EventEmitter,文档EventEmitter也适用。

socket.id

  • (串)

会话的唯一标识符,来自底层Client。

套房

  • (目的)

标识客房所在房间的字符串散列,按房间名称索引。

io.on('connection', (socket) => {
  socket.join('room 237', () => {
    let rooms = Objects.keys(socket.rooms);
    console.log(rooms); // [ <socket.id>, 'room 237' ]
  });
});

socket.client

  • (客户)

对基础Client对象的引用。

socket.conn

  • (engine.Socket)

引用底层Client传输连接(engine.io Socket对象)。这允许访问IO传输层,其仍然(主要)抽象实际的TCP / IP套接字。

socket.request

  • (请求)

一个getter代理,返回引用request底层引擎的引用Client。用于访问请求头,如Cookie或User-Agent。

socket.handshake

  • (目的)

握手细节:

{
  headers: /* the headers sent as part of the handshake */,
  time: /* the date of creation (as string) */,
  address: /* the ip of the client */,
  xdomain: /* whether the connection is cross-domain */,
  secure: /* whether the connection is secure */,
  issued: /* the date of creation (as unix timestamp) */,
  url: /* the request URL string */,
  query: /* the query object */
}

用法:

io.use((socket, next) => {
  let handshake = socket.handshake;
  // ...
});

io.on('connection', (socket) => {
  let handshake = socket.handshake;
  // ...
});

socket.use(fn)

  • fn (功能)

注册一个中间件,这是一个函数,它为每个传入Packet和接收作为参数的数据包和一个可选地将执行延迟到下一个注册的中间件的函数。

传递给中间件回调的错误作为特殊error数据包发送给客户端。

io.on('connection', (socket) => {
  socket.use((packet, next) => {
    if (packet.doge === true) return next();
    next(new Error('Not a doge error'));
  });
});

socket.send([... args] [,ack])

  • args
  • ack (功能)
  • 返回 Socket

发送一个message事件 请参见socket.emit(eventName [,... args] [,ack])

socket.emit(eventName [,... args] [,ack])

(覆盖EventEmitter.emit)

  • eventName (串)
  • args
  • ack (功能)
  • 返回 Socket

将一个事件发送到由字符串名称标识的套接字。可以包括任何其他参数。支持所有可序列化的数据结构,包括Buffer。

socket.emit('hello', 'world');
socket.emit('with-binary', 1, '2', { 3: '4', 5: new Buffer(6) });

该ack参数是可选的,并且将被客户端的答案调用。

io.on('connection', (socket) => {
  socket.emit('an event', { some: 'data' });

  socket.emit('ferret', 'tobi', (data) => {
    console.log(data); // data will be 'woot'
  });

  // the client code
  // client.on('ferret', (name, fn) => {
  //   fn('woot');
  // });

});

socket.on(eventName,callback)

(继承自EventEmitter)

  • eventName (串)
  • callback (功能)
  • 返回 Socket

为给定的事件注册一个新的处理程序。

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.once(eventName,listener)

socket.removeListener(eventName,listener)

socket.removeAllListeners([eventName])

socket.eventNames()

继承EventEmitter(与此处未提及的其他方法一起)。请参阅该events模块的Node.js文档。

socket.join(room [,callback])

  • room (串)
  • callback (功能)
  • Socket链接返回

将客户端添加到room,并且可选地启动带有err签名的回调(如果有)。

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
  });
});

加入房间的机制由Adapter已配置的(见Server#adapter上文)处理,默认为socket.io-adapter

为了方便起见,每个插座自动加入由其ID标识的房间(参见Socket#id)。这样可以轻松地向其他套接字广播消息:

io.on('connection', (socket) => {
  socket.on('say to someone', (id, msg) => {
    // send a private message to the socket with the given id
    socket.to(id).emit('my message', msg);
  });
});

socket.join(rooms [,callback])

  • rooms (阵列)
  • callback (功能)
  • Socket链接返回

将客户端添加到房间列表中,并可选地启用具有err签名的回调(如果有)。

socket.leave(room [,callback])

  • room (串)
  • callback (功能)
  • Socket链接返回

从中删除客户端room,并可选地启动带有err签名的回调(如果有)。

断开后房间自动关闭。

socket.to(room)

  • room (串)
  • Socket链接返回

为随后的事件发射设置一个修饰符,事件只会广播到已加入给定的客户端room(套接字本身被排除)。

要发射到多个房间,可以to多次打电话。

io.on('connection', (socket) => {
  // to one room
  socket.to('others').emit('an event', { some: 'data' });
  // to multiple rooms
  socket.to('room1').to('room2').emit('hello');
  // a private message to another socket
  socket.to(/* another socket id */).emit('hey');
});

注意:广播时不支持确认。

socket.in(room)

socket.to(房间)的同义词。

socket.compress(value)

  • value (布尔值)是否跟随数据包将被压缩
  • Socket链接返回

为后续事件发射设置一个修改器,只有当值为事件数据时才会被压缩true。默认为true不调用方法。

io.on('connection', (socket) => {
  socket.compress(false).emit('uncompressed', "that's rough");
});

socket.disconnect(close)

  • close (Boolean)是否关闭底层连接
  • 返回 Socket

断开此客户端。如果值为close true,则关闭底层连接。否则,它只是断开命名空间。

io.on('connection', (socket) => {
  setTimeout(() => socket.disconnect(true), 5000);
});

旗:'广播'

为后续事件发射设置一个修改器,事件数据只会广播到每个套接字,但发送方。

io.on('connection', (socket) => {
  socket.broadcast.emit('an event', { some: 'data' }); // everyone gets it but the sender
});

旗:'volatile'

为后续事件发射设置修改器,如果客户端尚未准备好接收消息(因为网络缓慢或其他问题,或者因为通过长轮询连接并处于请求中间),则事件数据可能丢失响应周期)。

io.on('connection', (socket) => {
  socket.volatile.emit('an event', { some: 'data' }); // the client may or may not receive it
});

事件:'断开'

  • reason (String)断开连接的原因(客户端或服务器端)

在断开时触发。

io.on('connection', (socket) => {
  socket.on('disconnect', (reason) => {
    // ...
  });
});

事件:'error'

  • error (Object)错误对象

发生错误时发生。

io.on('connection', (socket) => {
  socket.on('error', (error) => {
    // ...
  });
});

事件:'断开连接'

  • reason (String)断开连接的原因(客户端或服务器端)

当客户端断开连接(但尚未离开rooms)时触发。

io.on('connection', (socket) => {
  socket.on('disconnecting', (reason) => {
    let rooms = Object.keys(socket.rooms);
    // ...
  });
});

这些是不能用作事件名称的保留事件(以及connect,newListener和removeListener)。

客户端

所述Client类表示输入的传输(engine.io)连接。A Client可以与Socket属于不同Namespaces的许多多路复用s 相关联。

client.conn

  • (engine.Socket)

对基础engine.io Socket连接的引用。

client.request

  • (请求)

一个getter代理,返回引用requestengine.io连接的引用。用于访问请求头,如Cookie或User-Agent。



以上内容是否对您有帮助:
在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号