socket.io

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)載請附上博文鏈接!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容