socket.io 服務(wù)端API

2018-10-18 11:06 更新

服務(wù)端 | Server


Exposed byrequire('socket.io')。

新服務(wù)器 (httpServer[, options])

  • httpServer (http.Server)要綁定的服務(wù)器。
  • options (目的)
    • path (String):捕獲路徑的名稱(/socket.io
    • serveClient (Boolean):是否提供客戶端文件(true
    • adapter (適配器):適配器使用。默認(rèn)為Adapter 與基于內(nèi)存的socket.io附帶的實(shí)例。請參閱 socket.io-adapter
    • origins (String):允許的originins(*
    • parser (Parser):解析器使用。默認(rèn)為Parser socket.io附帶的實(shí)例。請參閱 socket.io-parser

有和沒有工作new:

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

傳遞給socket.io的相同選項(xiàng)始終傳遞給engine.io Server創(chuàng)建的選項(xiàng)。請參閱engine.io 選項(xiàng)作為參考。

其中:

  • pingTimeout (Number):有多少ms沒有乒乓包考慮連接close(60000)
  • pingInterval (Number):發(fā)送新的ping packet(25000)之前有多少ms 。

這兩個(gè)參數(shù)將在客戶端知道服務(wù)器不再可用之前影響延遲。例如,如果底層TCP連接由于網(wǎng)絡(luò)問題而未正確關(guān)閉,則pingTimeout + pingInterval在獲取disconnect事件之前,客戶端可能必須等待最多ms 。

  • transports (Array <String>):傳輸以允許連接到(['polling', 'websocket'])。

注意:順序很重要。默認(rèn)情況下,首先建立長輪詢連接,然后如果可能,升級到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 (數(shù)字)一個(gè)要聽的端口(一個(gè)新的http.Server將被創(chuàng)建)
  • options (目的)

請參閱上面的可用選項(xiàng)。

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

新服務(wù)器(選項(xiàng))

  • options (目的)

請參閱上面的可用選項(xiàng)。

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連接的服務(wù)器(請參閱Server#attach)將擔(dān)任客戶端文件。默認(rèn)為true。此方法attach調(diào)用后無效。如果沒有提供參數(shù),則此方法返回當(dāng)前值。

// 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

設(shè)置的路徑value下,其engine.io與靜態(tài)文件將送達(dá)。默認(rèn)為/socket.io。如果沒有提供參數(shù),則此方法返回當(dāng)前值。

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

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

server.adapter([value])

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

設(shè)置適配器value。默認(rèn)為Adapter與基于內(nèi)存的socket.io附帶的實(shí)例。請參閱socket.io-adapter。如果沒有提供參數(shù),則此方法返回當(dāng)前值。

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

設(shè)置允許的來源value。默認(rèn)為允許的任何來源。如果沒有提供參數(shù),則此方法返回當(dāng)前值。

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

server.origins(fn)

  • fn (功能)
  • 返回 Server

提供了一個(gè)函數(shù)取兩個(gè)參數(shù)origin:String和callback(error, success),其中success是說明產(chǎn)地,是否允許或不允許一個(gè)布爾值。

潛在缺點(diǎn):

  • 在某些情況下,如果不可能確定origin它可能有價(jià)值*
  • 由于此功能將針對每個(gè)請求執(zhí)行,建議使該功能盡可能快地工作
  • 如果socket.io與之一起使用Express,則CORS頭將僅受到socket.io請求的影響??爝f可以使用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)要附加的服務(wù)器
  • options (目的)

使用提供的(可選)附加Server到engine.io實(shí)例。httpServeroptions

server.attach(port [,options])

  • port (Number)要偵聽的端口
  • options (目的)

Server使用提供的options(可選)將新的http.Server 附加到engine.io實(shí)例。

server.listen(httpServer [,options])

server.attach的同義詞(httpServer [,options])。

server.listen(port [,options])

server.attach(port [,options])的同義詞。

server.bind(engine)

  • engine (engine.Server)
  • 返回 Server

僅限高級使用。將服務(wù)器綁定到特定的engine.io Server(或兼容API)實(shí)例。

server.onconnection(socket)

  • socket (engine.Socket)
  • 返回 Server

僅限高級使用。socket.io從傳入的engine.io(或兼容的API)創(chuàng)建一個(gè)新的客戶端Socket。

server.of(nsp)

  • nsp (串)
  • 返回 Namespace

Namespace通過其路徑名標(biāo)識符初始化并檢索給定的nsp。如果命名空間已經(jīng)被初始化,它會立即返回。

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

server.close([callback])

  • callback (功能)

關(guān)閉socket.io服務(wù)器。該callback參數(shù)是可選的,在關(guān)閉所有連接將被調(diào)用。

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

覆蓋默認(rèn)方法以生成您的自定義套接字ID。

該函數(shù)以節(jié)點(diǎn)請求object(http.IncomingMessage)作為第一個(gè)參數(shù)被調(diào)用。

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

#命名空間

表示在由路徑名(例如:)標(biāo)識的給定范圍內(nèi)連接的套接字池/chat。

客戶端始終連接到/(主命名空間),然后可能連接到其他命名空間(使用相同的底層連接)。

namespace.name

  • (串)

命名空間標(biāo)識符屬性。

namespace.connected

  • (對象<插座>)

Socket連接到此命名空間的對象的哈希,由索引編號id。

namespace.adapter

  • (適配器)

該Adapter用于命名空間。在使用Adapter基于Redis的時(shí)候很有用,因?yàn)樗┞读斯芾砑褐械奶捉幼趾头块g的方法。

注意:可以訪問主命名空間的適配器io.of('/').adapter。

namespace.to(room)

  • room (串)
  • Namespace鏈接返回

為隨后的事件發(fā)射設(shè)置一個(gè)修飾符,事件只會廣播到已經(jīng)加入給定的客戶端room。

要發(fā)射到多個(gè)房間,可以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

向所有連接的客戶端發(fā)出事件。以下兩個(gè)是等效的:

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

注意:從命名空間發(fā)布時(shí),不支持確認(rèn)。

namespace.clients(callback)

  • callback (功能)

獲取連接到此命名空間的客戶機(jī)ID(跨所有節(jié)點(diǎn)(如果適用))。

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

獲取命名空間中所有客戶端的一個(gè)示例:

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

與廣播一樣,默認(rèn)是默認(rèn)命名空間('/')的所有客戶端:

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

namespace.use(fn)

  • fn (功能)

注冊一個(gè)中間件,這是一個(gè)為每個(gè)傳入執(zhí)行的功能Socket,并且接收套接字和可選地將執(zhí)行延遲到下一個(gè)注冊的中間件的參數(shù)。

傳遞給中間件回調(diào)的錯(cuò)誤作為特殊error數(shù)據(jù)包發(fā)送給客戶端。

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

事件:'連接'

  • socket (Socket)與客戶端的套接字連接

在客戶端連接時(shí)被觸發(fā)。

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

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

事件:'連接'

事件的同義詞:'connect'

旗:'volatile'

為后續(xù)事件發(fā)射設(shè)置修改器,如果客戶端未準(zhǔn)備好接收消息(因?yàn)榫W(wǎng)絡(luò)緩慢或其他問題,或者因?yàn)橥ㄟ^長輪詢連接并且處于請求中間),則事件數(shù)據(jù)可能丟失響應(yīng)周期)。

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

旗:'本地'

為隨后的事件發(fā)射設(shè)置修改器,事件數(shù)據(jù)將僅廣播到當(dāng)前節(jié)點(diǎn)(使用Redis適配器時(shí))。

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

#插座

A Socket是與瀏覽器客戶端進(jìn)行交互的基本類。A Socket屬于某個(gè)Namespace(默認(rèn)情況下/),并使用底層Client進(jìn)行通信。

應(yīng)該注意的Socket不直接與實(shí)際的底層TCP / IP有關(guān)socket,它只是該類的名稱。

在每個(gè)內(nèi)部Namespace,您還可以定義可以加入和離開的任意通道(稱為room)Socket。這提供了一種方便的方式來廣播到一組Socket(見Socket#to下文)。

在Socket類繼承自EventEmitter。本Socket類覆蓋了emit方法,并且不修改任何其他EventEmitter方法。所有在這里記錄的方法也可以作為EventEmitter方法(除了以外emit)由...實(shí)現(xiàn)EventEmitter,文檔EventEmitter也適用。

socket.id

  • (串)

會話的唯一標(biāo)識符,來自底層Client。

套房

  • (目的)

標(biāo)識客房所在房間的字符串散列,按房間名稱索引。

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

socket.client

  • (客戶)

對基礎(chǔ)Client對象的引用。

socket.conn

  • (engine.Socket)

引用底層Client傳輸連接(engine.io Socket對象)。這允許訪問IO傳輸層,其仍然(主要)抽象實(shí)際的TCP / IP套接字。

socket.request

  • (請求)

一個(gè)getter代理,返回引用request底層引擎的引用Client。用于訪問請求頭,如Cookie或User-Agent。

socket.handshake

  • (目的)

握手細(xì)節(jié):

{
  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 (功能)

注冊一個(gè)中間件,這是一個(gè)函數(shù),它為每個(gè)傳入Packet和接收作為參數(shù)的數(shù)據(jù)包和一個(gè)可選地將執(zhí)行延遲到下一個(gè)注冊的中間件的函數(shù)。

傳遞給中間件回調(diào)的錯(cuò)誤作為特殊error數(shù)據(jù)包發(fā)送給客戶端。

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

發(fā)送一個(gè)message事件 請參見socket.emit(eventName [,... args] [,ack])。

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

(覆蓋EventEmitter.emit)

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

將一個(gè)事件發(fā)送到由字符串名稱標(biāo)識的套接字??梢园ㄈ魏纹渌麉?shù)。支持所有可序列化的數(shù)據(jù)結(jié)構(gòu),包括Buffer。

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

該ack參數(shù)是可選的,并且將被客戶端的答案調(diào)用。

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

為給定的事件注冊一個(gè)新的處理程序。

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,并且可選地啟動(dòng)帶有err簽名的回調(diào)(如果有)。

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

加入房間的機(jī)制由Adapter已配置的(見Server#adapter上文)處理,默認(rèn)為socket.io-adapter。

為了方便起見,每個(gè)插座自動(dòng)加入由其ID標(biāo)識的房間(參見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簽名的回調(diào)(如果有)。

socket.leave(room [,callback])

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

從中刪除客戶端room,并可選地啟動(dòng)帶有err簽名的回調(diào)(如果有)。

斷開后房間自動(dòng)關(guān)閉。

socket.to(room)

  • room (串)
  • Socket鏈接返回

為隨后的事件發(fā)射設(shè)置一個(gè)修飾符,事件只會廣播到已加入給定的客戶端room(套接字本身被排除)。

要發(fā)射到多個(gè)房間,可以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');
});

注意:廣播時(shí)不支持確認(rèn)。

socket.in(room)

socket.to(房間)的同義詞。

socket.compress(value)

  • value (布爾值)是否跟隨數(shù)據(jù)包將被壓縮
  • Socket鏈接返回

為后續(xù)事件發(fā)射設(shè)置一個(gè)修改器,只有當(dāng)值為事件數(shù)據(jù)時(shí)才會被壓縮true。默認(rèn)為true不調(diào)用方法。

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

socket.disconnect(close)

  • close (Boolean)是否關(guān)閉底層連接
  • 返回 Socket

斷開此客戶端。如果值為close true,則關(guān)閉底層連接。否則,它只是斷開命名空間。

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

旗:'廣播'

為后續(xù)事件發(fā)射設(shè)置一個(gè)修改器,事件數(shù)據(jù)只會廣播到每個(gè)套接字,但發(fā)送方。

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

旗:'volatile'

為后續(xù)事件發(fā)射設(shè)置修改器,如果客戶端尚未準(zhǔn)備好接收消息(因?yàn)榫W(wǎng)絡(luò)緩慢或其他問題,或者因?yàn)橥ㄟ^長輪詢連接并處于請求中間),則事件數(shù)據(jù)可能丟失響應(yīng)周期)。

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

事件:'斷開'

  • reason (String)斷開連接的原因(客戶端或服務(wù)器端)

在斷開時(shí)觸發(fā)。

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

事件:'error'

  • error (Object)錯(cuò)誤對象

發(fā)生錯(cuò)誤時(shí)發(fā)生。

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

事件:'斷開連接'

  • reason (String)斷開連接的原因(客戶端或服務(wù)器端)

當(dāng)客戶端斷開連接(但尚未離開rooms)時(shí)觸發(fā)。

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

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

客戶端

所述Client類表示輸入的傳輸(engine.io)連接。A Client可以與Socket屬于不同Namespaces的許多多路復(fù)用s 相關(guān)聯(lián)。

client.conn

  • (engine.Socket)

對基礎(chǔ)engine.io Socket連接的引用。

client.request

  • (請求)

一個(gè)getter代理,返回引用requestengine.io連接的引用。用于訪問請求頭,如Cookie或User-Agent。



以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號