如果你使用的是標(biāo)準(zhǔn)化的JS庫,則暴露為io這一命名空間;如果你是用Node 編譯,則使用require('socket.io-client')。
引入socket.io的JS庫
<script src="/socket.io/socket.io.js"></script>
<script>
const socket = io('http://localhost');
</script>
導(dǎo)入socket.io模塊
const io = require('socket.io-client');
// or with import syntax
import io from 'socket.io-client';
表示協(xié)議版本號(hào)。
使用給定的URL創(chuàng)建一個(gè)新的Manager,并且嘗試重用一個(gè)已存在的Manager等待隨后調(diào)用,除非multiplex的選項(xiàng)為false,作用同force new connection:true或者forceNew: true。
一個(gè)新的socket實(shí)例將返回命名空間指定的socket,該命名空間由URL指定,默認(rèn)的為 / 。舉個(gè)栗子,如果url為http://localhost/users,則將會(huì)對(duì)http://localhost進(jìn)行傳輸連接,并且Socket.IO連接將會(huì)對(duì)/users建立連接。
你也也可以提供查詢參數(shù),直接將查詢參數(shù)添加到url上即可:
http://localhost/users?token=abc
詳情查看new Manager(url[, options])
默認(rèn)的,當(dāng)連接道不同的命名空間后一個(gè)單一的鏈接將會(huì)被使用。
const socket = io();
const adminSocket = io('/admin');
// a single connection will be established
注意:重用相同的命名空間將會(huì)創(chuàng)建兩個(gè)連接:
const socket = io();
const socket2 = io();
// will also create two distinct connections
自定義path
const socket = io('http://localhost', {
path: '/myownpath'
});
// server-side
const io = require('socket.io')({
path: '/myownpath'
});
這里,socket連接到admin命名空間,使用自定義的路徑mypath。
請(qǐng)求地址看起來像這樣:
localhost/mypath/?EIO=3&transport=polling&sid=<id>
命名空間將會(huì)作為數(shù)據(jù)的一部分被發(fā)送。
攜帶查詢參數(shù)
const socket = io('http://localhost?token=abc');
// server-side
const io = require('socket.io')();
// middleware
io.use((socket, next) => {
let token = socket.handshake.query.token;
if (isValid(token)) {
return next();
}
return next(new Error('authentication error'));
});
// then
io.on('connection', (socket) => {
let token = socket.handshake.query.token;
// ...
});
攜帶查詢選項(xiàng)
const socket = io({
query: {
token: 'cde'
}
});
查詢內(nèi)容可以在重新連接時(shí)更新:
socket.on('reconnect_attempt', () => {
socket.io.opts.query = {
token: 'fgh'
}
});
僅當(dāng)建立的是輪詢連接時(shí)才起作用(默認(rèn)為polling輪詢),當(dāng)使用websocket建立傳輸時(shí),自定義的請(qǐng)求頭將不會(huì)被添加,因?yàn)閃ebSockets握手信號(hào)不信任自定義的請(qǐng)求頭(詳細(xì)信息可以閱讀 WebSocket protocol RFC)
const socket = io({
transportOptions: {
polling: {
extraHeaders: {
'x-clientid': 'abc'
}
}
}
});
// 服務(wù)器端
const io = require('socket.io')();
// 中間件
io.use((socket, next) => {
let clientId = socket.handshake.headers['x-clientid'];
if (isValid(clientId)) {
return next();
}
return next(new Error('authentication error'));
});
僅當(dāng)通過websocket傳輸時(shí)
默認(rèn)的,長(zhǎng)輪詢連接會(huì)被首次創(chuàng)建,隨后升級(jí)到更好的傳輸方式(比如WebSocket)。
如果你喜歡挑戰(zhàn)性,這一部分可以被跳過。
const socket = io({
transports: ['websocket']
});
// on reconnection, reset the transports option, as the Websocket
// connection may have failed (caused by proxy, firewall, browser, ...)
socket.on('reconnect_attempt', () => {
socket.io.opts.transports = ['polling', 'websocket'];
});
攜帶自定義的解析器
默認(rèn)的解析器(詳細(xì)內(nèi)容查閱這里Socket.IO custom parsers)
const parser = require('socket.io-msgpack-parser'); // or require('socket.io-json-parser')
const socket = io({
parser: parser
});
// the server-side must have the same parser, to be able to communicate
const io = require('socket.io')({
parser: parser
});
這一選項(xiàng)同樣可通過engine.io-client初始化,查看參數(shù)
設(shè)置reconnection選項(xiàng),或者如果沒有傳遞參數(shù)則直接返回它。
設(shè)置reconnectionAttempts選項(xiàng),或者當(dāng)沒有參數(shù)時(shí)直接返回。
設(shè)置reconnectionDelay選項(xiàng),或者當(dāng)沒有參數(shù)時(shí)直接返回。
設(shè)置reconnectionDelayMax選項(xiàng),或者當(dāng)沒有參數(shù)時(shí)直接返回。
設(shè)置timeout選項(xiàng),或者當(dāng)沒有參數(shù)時(shí)直接返回。
如果manager使用autoConnect初始化為false,嘗試運(yùn)行一個(gè)新的連接。
這個(gè)回調(diào)函數(shù)參數(shù)時(shí)可選擇的,并且將會(huì)在錯(cuò)誤或者成功后被執(zhí)行一次。
同**manager.open([callbakc])
使用給定的命名空間創(chuàng)建一個(gè)新的Socket連接。
觸發(fā)連接錯(cuò)誤事件。
觸發(fā)連接超時(shí)事件
觸發(fā)成功連接的事件
觸發(fā)嘗試重新連接
觸發(fā)成功重新連接事件
觸發(fā)當(dāng)在reconnectionAttempts次數(shù)內(nèi)無法重新連接的錯(cuò)誤事件
當(dāng)請(qǐng)求ping發(fā)送到服務(wù)器端時(shí)。
當(dāng)接受到服務(wù)器端的pong時(shí)觸發(fā)。
標(biāo)志socket session一個(gè)獨(dú)一無二的符號(hào),在客戶端連接到服務(wù)器后被設(shè)置。
const socket = io('http://localhost');
console.log(socket.id); // undefined
socket.on('connect', () => {
console.log(socket.id); // 'G5p5...'
});
手動(dòng)打開socket
const socket = io({
autoConnect: false
});
// ...
socket.open();
同樣,也可以重新連接:
socket.on('disconnect', () => {
socket.open();
});
用法同socket.open()
發(fā)送一個(gè)message事件,詳細(xì)查看socket.emit(eventName[, ...args][, ack]).
通過提供的name時(shí)間名稱向socket標(biāo)志發(fā)送事件,任何其他的參數(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ù)將用來響應(yīng)服務(wù)器用來確認(rèn)消息的應(yīng)答。
socket.emit('ferret', 'tobi', (data) => {
console.log(data); // data will be 'woot'
});
// server:
// io.on('connection', (socket) => {
// socket.on('ferret', (name, fn) => {
// fn('woot');
// });
// });
注冊(cè)一個(gè)新的響應(yīng)服務(wù)器事件的事件處理器。
socket.on('news', (data) => {
console.log(data);
});
// with multiple arguments
socket.on('news', (arg1, arg2, arg3, arg4) => {
// ...
});
// with callback
socket.on('news', (cb) => {
cb(0);
});
這個(gè)socket實(shí)際上繼承Emitter類的所有方法,比如**hashListener"",once,off(用來移除一個(gè)事件監(jiān)聽器)。
設(shè)置修改器,是否對(duì)向服務(wù)器傳輸?shù)臄?shù)據(jù)進(jìn)行壓縮。默認(rèn)為true,即壓縮。
socket.compress(false).emit('an event', { some: 'data' });
手動(dòng)關(guān)閉客戶端對(duì)服務(wù)器的鏈接
用法同 socket.close()。
連接成功后執(zhí)行該函數(shù)。
socket.on('connect', () => {
// ...
});
// note: you should register event handlers outside of connect,
// so they are not registered again on reconnection
socket.on('myevent', () => {
// ...
});
連接錯(cuò)誤觸發(fā)事件處理器。
socket.on('connect_error', (error) => {
// ...
});
丟失連接時(shí)觸發(fā)時(shí)間處理器
socket.on('disconnect', (timeout) => {
// ...
});
成功的重連時(shí)觸發(fā)時(shí)間處理器
socket.on('reconnect', (timeout) => {
// ...
});
成功的重連時(shí)觸發(fā)時(shí)間處理器
socket.on('reconnect_attempt', (timeout) => {
// ...
});
嘗試重連時(shí)觸發(fā)時(shí)間處理器
socket.on('reconnecting', (timeout) => {
// ...
});
重連錯(cuò)誤時(shí)觸發(fā)時(shí)間處理器
socket.on('reconnect_error', (timeout) => {
// ...
});
socket.on('reconnect_failed', (timeout) => {
// ...
});
socket.on('ping', (timeout) => {
// ...
});
socket.on('pong', (timeout) => {
// ...
});
更多建議: