iis服务器助手广告广告
返回顶部
首页 > 资讯 > 前端开发 > JavaScript >JavaScript实现即时通讯的4种方案
  • 261
分享到

JavaScript实现即时通讯的4种方案

2024-04-02 19:04:59 261人浏览 安东尼
摘要

目录前言:1. Http + ajax2. websocket3. SSE前言: 服务端如何将数据推送到浏览器,一般来说,WEB端即时通讯技术因受限于浏览器的设计限制,一直以来实现起

前言:

服务端如何将数据推送到浏览器,一般来说,WEB端即时通讯技术因受限于浏览器的设计限制,一直以来实现起来并不容易,这里总结了4种方式。

1. http + ajax

XMLHttpRequest在和服务端进行数据交互时存在四种状态,很多时候的判断是readyState为4时,从response获取服务端响应结果。其实readyState等于3的时候就可以获取到服务端的部分数据了。

可以利用这个属性实现服务端推送。

比如服务使用http创建服务,每间隔1s的时候通过write方法返回一段文本,但是不要调用end方法。

const http = require('http');
const fs = require('fs');

const app = http.createServer((req, res) => {
    // 设置响应头
    res.setHeader('Content-type', 'application/JSON; charset=utf-8');
    res.setHeader('Cache-Control', 'max-age=0'); // 没有缓存
    let num = 0;
    // 地柜返回
    const send = () => {
        if (num > 20) {
            res.end();
            return;
        }
        num++;
        const data = Math.random() + '';
        res.write(data, 'utf8');
        setTimeout(send, 1000);
    }
    send();
});

app.listen(8081, () => {
    console.log('127.0.0.1:8081');
})

前端监听XMLHttpRequestonreadystatechange事件,每当服务器返回一段数据都会触发一次onreadystatechange事件,可以从responseText中得到当前获取到的全部数据。

var xhr = new XMLHttpRequest();
xhr.open('GET', '/api');
xhr.timeout = 30000;
xhr.responseType = 'text';
xhr.onreadystatechange = function () {
    if (this.readyState == 3) { // 分段获取服务端返回的数据
        console.log(this.responseText);
    }
    if (this.readyState == 4) {
        if (this.status >= 200 && this.status < 300 || this.status == 304) {
            // this.response
        } else {
            // this.statusText
        }
    }
}
xhr.send()

2. webSocket

websocket具有三个优点,双向通信,自动跨域,性能高。最主要的是可以传输多种格式的数据。WebSocket 协议在2008年诞生,2011年成为国际标准。所有浏览器都已经支持了,也是应用很广泛的一种即时通信协议。

websocketHTML5新增的API,属于浏览器或者前端的内容。后端用的是socket,socket协议的历史相当古老基本四十年前就已经存在了。在H5中websocket自带一些安全的措施,而原生的socket就没什么安全性可言了。

客户端浏览器通过实例化Websocket,传入服务地址创建websocket链接,message中会接收到服务端推送的数据,也可通过send方法向服务端发送数据。

const ws = new Websocket('ws://127.0.0.1:8080/api');
// 原生没有emit,自己封装一个
ws.emit = function(name, ...args) {
    ws.send(jsON.stringify({
        name,
        data: [...args]
    }))
}
ws.onopen = function() {
    console.log('链接上了');
    // ws.send('dadadadadasda'); // 发送数据,只有一个参数一个大字符串
    ws.emit('msg', 12, 5, 8);
}; // 已经链接
ws.onmessage = function() {
    console.log('接收到消息了')
}; // 收到数据
ws.onclose = function() {
    console.log('断开链接了')
}; // 断开了

node中想要实现socket可以借助node原生的net模块,这是一个相对底层的网络模块,是一个tcp的库。net是http的底层,很多东西都需要自己去实现,比如这里可以使用net.createServer来创建服务。

websocket也是给予http的,先通过http请求到服务,会携带一个upgradewebsocket的请求头,表示希望升级为websocket,这个时候服务可以返回101状态码,表示进行服务可以升级。

const http = require('http');
const net = require('net'); // TCP的库,可以理解为原生的Socket
const crypto = require('crypto'); // 借助加密库实现一些安全性

const server = net.createServer(sock=> {
    console.log('链接上了');
    sock.on('end', () => {
        console.log('客户端断开了')
    }); // 断开

    sock.once('data', (data) => {
        console.log('hand shake start...');
        // 最先过来的是http头
        const str = data.toString();
        // 将http头用\r\n切开
        let lines = str.split('\r\n');
        // 删除第一行和最后一行,因为没啥用
        lines = lines.slice(1, lines.length - 2);
        // 将所有请求头通过'分号空格'切开
        const headers = {};
        lines.forEach(line => {
            const [key, value ] = line.split(': ');
            // 将请求头变成小写
            headers[key.toLowerCase()] = val;
        })
        // http协议转websocket会传入upgrade为websocket
        if (headers['upgrade'] != 'websocket') {
            console.log('其他协议,暂不支持');
            sock.end();
        } else if (headers['sec-websocket-version'] != 13) {
            console.log('不兼容不是13的版本');
            sock.end();
        } else {
            const key = headers['sec-websocket-key'];
            // 13版本的源码是258E,可以百度的到
            const mask = '258EAFA5-47DA-95CA-C5AB0DC85B11';
            // 需要把key和mask加在一起,然后用sha1加密,再变成base64,还给客户端
            // sha1(key + mask) -> base64 -> client;
            const hash = crypto.createHash('sha1');
            hash.update(key + mask);
            const tokey = hash.digest('base64');
            // 数据以HTTP发回客户端,因为验证的过程还是http阶段, 状态值为101(正在切换协议,协议升级 Switching Protocols)
            sock.write('HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: ' + tokey + '\r\n'); // Upgrade: websocket告诉浏览器升级为websocket,冒号要有空格
            // 至此,握手已经结束了。因为握手的过程只有一次,所以不要用on处理,用once处理
            // 从这里开始,才是真正的数据,以后所有的数据都走这里,所以用on处理
            sock.on('data', data => {
                // 获取到的数据
                // 不过数据是一个buffer的数据包,解析起来比较麻烦。
                console.log(data);
            })
        }
    }); // 有数据过来
}).listen(8080);

上面介绍的是websocket的一个实现原理,项目中可以直接使用socket.io这个库。

前端代码如下:

const sock = io.connect('ws://127.0.0.1:8080/api');
sock.on('connect', () => {
    console.log('已链接');
    sock.emit('aaa', 12, 5,8);
    sock.on('time', (ts) => {
        console.loh(ts);
    })
});
sock.on('disconnect', () => {
    console.log('已断开');
});

服务端代码如下:

const http = require('http');
const io = require('socket.io');

// 创建http服务,开启8080端口号
const httpserver = http.createServer().listen(8080);
// socket监听http服务
const wsServer = io.listen(httpServer);

// 当有链接的时候
wsServer.on('connection', sock => {
    // 发送
    // sock.emit
    sock.emit('time', Date.now());
    // 接收
    sock.on('aaa', (a, b, c) => {
        console.loh(a, b, c);
    })
})

3. SSE

SSE全称是Server-Sent Events,指的是网页自动获取来自服务器的更新,也就是自动获取服务端推送至网页的数据,这是一个H5的属性,除了IE,其它标准浏览器基本都兼容。

实现方式和第二种有一些像,服务器向客户端声明要发送流信息,然后连续不断地发送过来。这时客户端是不会关闭连接的,会一直等着服务器发过来的新的数据流。比如音视频的媒体流就是这种机制。

SSE 只能服务器向浏览器发送数据,这点和第二种方式很像,能力上都不如websocket,优点是SSE使用更加简单,并且基于http协议,兼容性还可以(当然2022年了,没有啥是兼容性不可以的了)。

H5端使用EventSource对象,填入要请求的url地址就可以了。

var source = new EventSource('/api', {
    withCredentials: true
});
source.onopen = function () {
    console.log('链接已建立', this.readyState);
}
source.onmessage = function (event) {
    console.log('实时获取的数据', event.data);
}
source.onerror = function () {
    console.log('发生错误');
}
// 关闭
// source.close();

服务器向浏览器发送的 SSE 数据,首先必须设置响应头的Content-typetext/event-stream,且编码格式为utf-8。返回的数据格式必须为data: xxxx\n\n。除了data还有event,id,以及retry,可以参考Server-sent_events-mdn。

服务端代码如下:

const http = require('http');
const fs = require('fs');

const app = http.createServer((req, res) => {
    res.setHeader('Content-type', 'text/event-stream; charset=utf-8');
    res.setHeader('Cache-Control', 'max-age=0'); // 清楚缓存
    res.setHeader('Access-Control-Allow-Origin', 'http:127.0.0.1/');
    let num = 0;
    const send = () => {
        if (num > 20) {
            res.end();
            return;
        }
        num++;
        const data = Math.random() + '';
        res.write(`data: ${data}\n\n`, 'utf8');
        setTimeout(send, 1000);
    }
    send();
});

app.listen(8081, () => {
    console.log('127.0.0.1:8081');
})

到此这篇关于javascript实现即时通讯的 4 种方案的文章就介绍到这了,更多相关JavaScript实现即时通讯方案内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: JavaScript实现即时通讯的4种方案

本文链接: https://www.lsjlt.com/news/139033.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • JavaScript实现即时通讯的4种方案
    目录前言:1. http + ajax2. websocket3. SSE前言: 服务端如何将数据推送到浏览器,一般来说,Web端即时通讯技术因受限于浏览器的设计限制,一直以来实现起...
    99+
    2022-11-13
  • Python 4种实现定时任务的方案
    目录1.利用 while True: + sleep() 实现定时任务2.使用 Timeloop 库运行定时任务3.利用 threading.Timer 实现定时任务4.利用内置模块...
    99+
    2022-11-12
  • SpringBoot+WebSocket实现即时通讯的方法详解
    目录环境信息服务端实现导入依赖创建配置类创建一个注解式的端点并在其中通过配套注解声明回调方法服务端主动发送消息给客户端客户端实现Java客户端实现在前端环境(vue)中使用webso...
    99+
    2022-11-13
  • PHP和WebSocket: 实现即时通信的完美解决方案
    随着互联网的快速发展,越来越多的应用需要实现即时通信功能,比如在线聊天、实时数据监控等。而传统的 HTTP 协议并不适合这种场景,因为它是基于请求/响应的,必须客户端不断向服务器发送请求才能获取最新数据,这样带来了很大的开销和延迟。为了解决...
    99+
    2023-12-17
    PHP websocket 即时通信
  • PHP和WebSocket: 实现即时通信的完美解决方案
    随着互联网的快速发展,越来越多的应用需要实现即时通信功能,比如在线聊天、实时数据监控等。而传统的 HTTP 协议并不适合这种场景,因为它是基于请求/响应的,必须客户端不断向服务器发送请求才能获取最新数据,这样带来了很大的开销和延迟。为了解决...
    99+
    2023-12-17
    PHP websocket 即时通信
  • SpringBoot实现WebSocket即时通讯的示例代码
    目录1、引入依赖2、WebSocketConfig 开启WebSocket3、WebSocketServer4、测试连接发送和接收消息5、在线测试地址6、测试截图1、引入依赖 <...
    99+
    2022-11-13
  • 网站即时通讯功能的实现方法有哪些方面
    本篇内容介绍了“网站即时通讯功能的实现方法有哪些方面”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!我们先以聊天室为例来讲, web...
    99+
    2023-06-10
  • Java实现定时器的4种方法
    Java实现定时器的4种方法:1. 使用Timer类:Timer类是Java提供的一个定时器工具类,可以用它创建计划任务,可以一次性...
    99+
    2023-08-08
    Java
  • nodejs如何结合Socket.IO实现的即时通讯功能
    这篇文章主要为大家展示了“nodejs如何结合Socket.IO实现的即时通讯功能”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“nodejs如何结合Socket...
    99+
    2022-10-19
  • PHP和WebSocket: 实现即时通信的优化方法
    PHP和WebSocket: 实现即时通信的优化方法引言:随着互联网的快速发展,即时通信成为人们生活中必不可少的一部分。而在建立一个高效和可靠的即时通信系统中,WebSocket技术的应用变得越来越普遍,它可以实现双向实时通信,大大提高了用...
    99+
    2023-12-17
    优化 PHP websocket
  • vue中利用mqtt服务端实现即时通讯的步骤记录
    MQTT协议 MQTT(Message Queuing Telemetry Transport,消息队列遥测传输)是IBM开发的一个即时通讯协议,有可能成为物联网的重要组成部分。该...
    99+
    2022-11-12
  • PHP实现在线即时通讯系统消息的发送和接收
    随着人们生活方式的改变和网络技术的不断发展,即时通讯已经成为现代人必不可少的沟通方式之一。在这种趋势下,各种在线即时通讯系统应运而生。既然在不同地方的人可以在同一时间内交换消息,那么在线即时通讯系统是如何实现消息的传递的呢?本文将介绍通过 ...
    99+
    2023-05-24
    PHP 消息发送 在线通讯
  • Java之线程编程的4种方法实现案例讲解
    1、继承Thread public class T4 { public static void main(String[] args) { System.out.print...
    99+
    2022-11-12
  • java实现web实时消息推送的七种方案
    目录引言什么是消息推送(push)短轮询长轮询iframe流SSE (我的方式)MQTTWebsocket自定义推送Github地址引言 做了一个小破站,现在要实现一个站内信web消...
    99+
    2022-11-13
  • Python实现定时任务的八种方案详解
    目录利用while True: + sleep()实现定时任务使用Timeloop库运行定时任务利用threading.Timer实现定时任务利用内置模块sched实现定时任务利用调...
    99+
    2022-11-13
  • 如何设计一个安全的MySQL表结构来实现即时通讯功能?
    如何设计一个安全的MySQL表结构来实现即时通讯功能?随着互联网的快速发展,即时通讯成为了人们生活中不可或缺的一部分。而为了保证即时通讯的安全性,一个合理且安全的MySQL表结构设计也变得至关重要。本文将介绍如何设计一个安全的MySQL表结...
    99+
    2023-10-31
    MySQL 安全性 通讯功能
  • C语言通过三种方法实现属于你的通讯录
    目录一、基础版本1.1 通讯录的个人信息(结构体来实现)1.2通讯录名单1.3人员初始化1.4菜单1.5主函数二、功能的实现2.1、增加人数2.2、删除人数2.3、查找2.4、展示2...
    99+
    2022-11-21
    C语言实现通讯录 C语言 通讯录
  • PHP使用Socket和EPOLL实现在线即时通讯系统消息的发送和接收
    随着互联网的不断发展,即时通讯(IM)系统已成为人们生活、工作中不可或缺的工具。而其中,如何保证消息的快速传输和实时性就成为了系统设计中至关重要的一环。本文将介绍如何使用PHP的Socket和EPOLL实现在线即时通讯系统消息的发送和接收。...
    99+
    2023-05-24
    PHP socket EPOLL
  • 通过Python实现电脑定时关机的两种方法
    目录导语一、普通人关机二、程序员关机1)Pyqt5界面化小程序​2)Tkinter界面化小程序导语 无论家用电脑还是公司的电脑,定时开关机都是一个非常实用的功能,只是一般都不太受关注...
    99+
    2022-11-12
  • 前端实时通信的8种方式及其优缺点和实现方式
    1.短轮询 短轮询的原理很简单,每隔一段时间客户端就发出一个请求,去获取服务器最新的数据,一定程度上模拟实现了即时通讯。 优点:兼容性强,实现非常简单缺点:延迟性高,请求中有大半是无...
    99+
    2022-11-13
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作