Socket.IO是一個WebSocket庫,包括了客戶端的js和服務(wù)器端的nodejs,它的目標(biāo)是構(gòu)建可以在不同瀏覽器和移動設(shè)備上使用的實(shí)時應(yīng)用
socket.io的特點(diǎn)
易用性:socket.io封裝了服務(wù)端和客戶端,使用起來非常簡單方便。
跨平臺:socket.io支持跨平臺,這就意味著你有了更多的選擇,可以在自己喜歡的平臺下開發(fā)實(shí)時應(yīng)用。
自適應(yīng):它會自動根據(jù)瀏覽器從WebSocket、AJAX長輪詢、Iframe流等等各種方式中選擇最佳的方式來實(shí)現(xiàn)網(wǎng)絡(luò)實(shí)時應(yīng)用,非常方便和人性化,而且支持的瀏覽器最低達(dá)IE5.5。
安裝
使用npm安裝socket.io
npm install socket.io
啟動一個簡單的服務(wù)
新建目錄,新建app.js, index.html
app.js 服務(wù)端
var express = require('express');
var path = require('path');
var app = express();
app.get('/', function (req, res) {
? ? res.sendFile(path.resolve('index.html'));
});
var server = require('http').createServer(app);
var io = require('socket.io')(server);
io.on('connection', function (socket) {
? ? console.log('客戶端已經(jīng)連接');
? ? socket.on('message', function (msg) {
? ? ? ? console.log(msg);
? ? ? ? socket.send('sever:' + msg);
? ? });
});
server.listen(80);
index.html 客戶端
服務(wù)端運(yùn)行后會在根目錄動態(tài)生成socket.io的客戶端js文件 客戶端可以通過固定路徑/socket.io/socket.io.js添加引用 客戶端加載socket.io文件后會得到一個全局的對象io connect函數(shù)可以接受一個url參數(shù),url可以socket服務(wù)的http完整地址,也可以是相對路徑,如果省略則表示默認(rèn)連接當(dāng)前路徑 創(chuàng)建index.html文件
<!DOCTYPE html>
<html lang="en">
<head>
? ? <meta charset="UTF-8">
? ? <meta name="viewport" content="width=device-width, initial-scale=1.0">
? ? <meta http-equiv="X-UA-Compatible" content="ie=edge">
? ? <title>socket.io</title>
</head>
<body>
? ? <h2>socket.io</h2>
<script src="/socket.io/socket.io.js"></script> // 引用腳本,固定寫法
window.onload = function(){
? ? var socket = io.connect('/');
? ? //監(jiān)聽與服務(wù)器端的連接成功事件
? ? socket.on('connect',function(){
? ? ? ? ? ? ? ? console.log('連接成功');
? ? ? ? ? ? });
? ? ? ? ? ? //監(jiān)聽與服務(wù)器端斷開連接事件
? ? ? ? ? ? socket.on('disconnect',function(){
? ? ? ? ? ? ? console.log('斷開連接');
? ? ? ? ? ? });
? ? ? ? };
</body>
</html>
發(fā)送消息
成功建立連接后,我們可以通過socket對象的send函數(shù)來互相發(fā)送消息
修改index.html 如下:
<!DOCTYPE html>
<html lang="en">
<head>
? ? <meta charset="UTF-8">
? ? <meta name="viewport" content="width=device-width, initial-scale=1.0">
? ? <meta http-equiv="X-UA-Compatible" content="ie=edge">
? ? <title>socket.io</title>
</head>
<body>
? ? <h2>socket.io</h2>
<script src="/socket.io/socket.io.js"></script> // 引用腳本,固定寫法
window.onload = function(){
? ? var socket = io.connect('/');
? ? //監(jiān)聽與服務(wù)器端的連接成功事件
? ? socket.on('connect',function(){
? ? ? ? ? ? ? ? console.log('連接成功');
? ? ? ? ? ? ? ? //客戶端連接成功后發(fā)送消息'welcome'
? ? ? ? ? ? ? ? ? socket.send('welcome');
? ? ? ? ? ? });
? ? ? ? ? ? //客戶端收到服務(wù)器發(fā)過來的消息后觸發(fā)
? ? ? ? ? ? socket.on('message',function(message){
? ? ? ? ? ? ? console.log(message);
? ? ? ? ? ? });
? ? ? ? ? ? //監(jiān)聽與服務(wù)器端斷開連接事件
? ? ? ? ? ? socket.on('disconnect',function(){
? ? ? ? ? ? ? console.log('斷開連接');
? ? ? ? ? ? });
? ? ? ? };
</body>
</html>
app.js 修改如下
let express = require('express')
let http = require('http')
let app = express()
app.use(express.static(__dirname))
app.get('/', function (res, req) {
? ? res.header('Content-Type', 'text/html;charset=utf8')
? ? res.sendFile(path.resolve('index.html'))
})
let server = http.createServer(app)
// 因?yàn)閣ebsocket協(xié)議是要依賴http協(xié)議實(shí)現(xiàn)握手的,所以需要把httpServer的實(shí)例傳遞給socket.io
let socketIo = require('socket.io')
let io = socketIo(server)
// 在服務(wù)器監(jiān)聽客戶端的鏈接
io.on('connection', socket => {
? ? console.log('客戶端連接到服務(wù)器')
? ? // 監(jiān)聽接受客戶端發(fā)過來的消息
? ? socket.on('message', msg => {
? ? ? ? console.log('客戶端等候掃服務(wù)器的消息', msg)
? ? ? ? // 像客戶端發(fā)送數(shù)據(jù)
? ? ? ? socket.send(`服務(wù)器說:${msg}`)
? ? })
? ? socket.on('disconect', function () {
? ? ? ? console.log('斷開連接')
? ? })
? ? socket.on('error', () => {
? ? ? ? console.log('連接錯誤')
? ? })
})
server.listen(9999)
分析
send函數(shù)只是emit的封裝
function send(){
? var args = toArray(arguments);
? args.unshift('message');
? this.emit.apply(this, args);
? return this;
emit函數(shù)有兩個參數(shù)
第一個參數(shù)是自定義的事件名稱,發(fā)送方發(fā)送什么類型的事件名稱,接收方就可以通過對應(yīng)的事件名稱來監(jiān)聽接收
第二個參數(shù)是要發(fā)送的數(shù)據(jù)
服務(wù)端事件
事件名稱 含義
connection 客戶端成功連接到服務(wù)器
message 接收到客戶端發(fā)送的消息
disconnect 客戶端斷開連接
error 監(jiān)聽錯誤
客戶端事件
事件名稱 含義
connect 成功連接到服務(wù)器
message 接收到服務(wù)器發(fā)送的消息
disconnect 客戶端斷開連接
error 監(jiān)聽錯誤
劃分命名空間
可以把服務(wù)劃分成多個命名空間,默認(rèn)/不同空間不能通信
可以把服務(wù)分成多個命名空間,默認(rèn)/,不同空間內(nèi)不能通信
io.on('connection', socket => {});
io.of('/news').on('connection', socket => {});
客戶端鏈接命名空間
let socket = io('http://localhost/');
let socket = io('http://localhost/news');
房間
可以把一個命名空間分成多個房間,一個客戶端可以同時進(jìn)入多個房間。
如果大大廳里廣播 ,那么所有在大廳里的客戶端和任何房間內(nèi)的客戶端都能收到消息。
所有在房間里的廣播和通信都不會影響到房間以外的客戶端
進(jìn)入房間
socket.join('chat');//進(jìn)入chat房間
離開房間
socket.leave('chat');//離開chat房間
全局廣播
廣播就是把消息發(fā)送給多個客戶端
向大廳和房間廣播
io.emit('message','全局廣播');
像除了自己之外的其它客戶端廣播
socket.broadcast.emit('message', msg);
房間內(nèi)廣播
向房間內(nèi)廣播, 從服務(wù)器的角度來提交事件,提交者會包含在內(nèi)
向myRoom廣播一個事件,在此房間內(nèi)除了自己外的所有客戶端都會收到消息
io.in('myRoom').emit('message', msg);
io.of('/news').in('myRoom').emit('message',msg);
向房間內(nèi)廣播, 從客戶端的角度來提交事件,提交者會排除在外
//向myRoom廣播一個事件,在此房間內(nèi)除了自己外的所有客戶端都會收到消息
socket.broadcast.to('myroom').emit('message', msg);
---------------------
作者:Corner1990
來源:CSDN
原文:https://blog.csdn.net/weixin_33768153/article/details/84314607
版權(quán)聲明:本文為博主原創(chuàng)文章,轉(zhuǎn)載請附上博文鏈接!