Websocket 原理,使用方法,心跳包机制(你想要了解的知识点!)

本文详细介绍了WebSocket协议的原理,包括其与HTTP协议的区别,以及在聊天、弹幕、在线教育等场景的应用。此外,还阐述了WebSocket的使用方法,特别是在Django框架下的实践。最后,讨论了WebSocket心跳包机制的重要性,以及如何在Vue和Django中实现心跳检测,确保连接稳定性。
摘要由CSDN通过智能技术生成

目录:

一. Websocket原理

什么是webSocket?

  • webSocket是一种在单个TCP连接上进行全双工通信的协议
  • 客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。
  • 浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输
  • 远古时期解决方案就是轮训:客户端以设定的时间间隔周期性地向服务端发送请求,频繁地查询是否有新的数据改动(浪费流量和资源)

webSocket应用场景?

  • 聊天软件:最著名的就是微信,QQ,这一类社交聊天的app
  • 弹幕:各种直播的弹幕窗口
  • 在线教育:可以视频聊天、即时聊天以及其与别人合作一起在网上讨论问题…

图解http与webSocket比较

  • 浏览器通过 JavaScript 向服务端发出建立 WebSocket 连接的请求
  • 在 WebSocket 连接建立成功后,客户端和服务端就可以通过 TCP连接传输数据。
  • 因为WebSocket 连接本质上是 TCP 连接,不需要每次传输都带上重复的头部数据
  • http协议是用在应用层的协议,他是基于tcp协议的,http协议建立链接也必须要有三次握手才能发送信息。
    http链接分为短链接,长链接,短链接是每次请求都要三次握手才能发送自己的信息。即每一个request对应一个response。长链接是在一定的期限内保持链接。保持TCP连接不断开。客户端与服务器通信,必须要有客户端发起然后服务器返回结果。客户端是主动的,服务器是被动的。
    WebSocket他是为了解决客户端发起多个http请求到服务器资源浏览器必须要经过长时间的轮训问题而生的,他实现了多路复用,他是全双工通信。在webSocket协议下客服端和浏览器可以同时发送信息。
    建立了WenSocket之后服务器不必在浏览器发送request请求之后才能发送信息到浏览器。这时的服务器已有主动权想什么时候发就可以发送信息到服务器。而且信息当中不必在带有head的部分信息了与http的长链接通信来说,这种方式,不仅能降低服务器的压力。而且信息当中也减少了部分多余的信息。

在这里插入图片描述

websocket原理:

  • websocket首先借助http协议(通过在http头部设置属性,请求和服务器进行协议升级,升级协议websocket的应用层协议)
  • 建立好和服务器之间的数据流,数据流之间底层还是依靠TCP协议;
  • websocket会接着使用这条建立好的数据流和服务器之间保持通信;
  • 由于复杂的网络环境,数据流可能会断开,在实际使用过程中,我们在onFailure或者onClosing回调方法中,实现重连

二. webSocket使用

webSocket使用说明:

  • 如果你想为一个单独的视图处理一个websocklet连接可以使用accept_websocket装饰器,它会将标准的HTTP请求路由到视图中。
  • 使用require_websocke装饰器只允许使用WebSocket连接,会拒绝正常的HTTP请求。
  • 在设置中添加设置MIDDLEWARE_CLASSES=dwebsocket.middleware.WebSocketMiddleware这样会拒绝单独的视图实用websocket,必须加上accept_websocket
    装饰器。
  • 设置WEBSOCKET_ACCEPT_ALL=True可以允许每一个单独的视图实用websockets

Django的Websocket:

1)dwebsocket介绍

  • dwebsocket 是一个在 django 用来实现 websocket 服务端的三方模块,使用上手非常简单
  • 安装方式如下:pip install dwebsocket
  • git 地址:https://github.com/duanhongyi/dwebsocket

2)dwebsocket方法


首先是两个基本的装饰器,用来限定过滤 websocket 的连接
dwebsocket.accept_websocket   # 允许 http 与 websocket 连接
dwebsocket.require_websocke   # 只允许 websocket 连接

1.request.is_websocket() :如果是个websocket请求返回True,如果是个普通的http请求返回False,可以用这个方法区分它们。
2.request.websocket() :websocket请求建立之后,有一个websocket属性,如果request.is_websocket()False,这个属性将是None3.WebSocket.wait() :返回一个客户端发送的信息,在客户端关闭连接之前他不会返回任何值,这种情况下,方法将返回None
4.WebSocket.read() :如果没有从客户端接收到新的消息,read方法会返回一个新的消息,如果没有,就不返回。这是一个替代wait的非阻塞方法
5.WebSocket.count_messages() :返回消息队列数量
6.WebSocket.has_messages() : 如果有新消息返回True,否则返回False
7.WebSocket.send(message) :向客户端发送消息
8.WebSocket.__iter__() :websocket迭代器

HTML的Websocket:

1)响应事件:

复制代码
# 1. 创建一个WebSocket连接
var ws = new WebSocket("ws://127.0.0.1:8001/echo")

# 2. ws.onopen方法(当 ws 连接建立时触发)
ws.onopen = function () {
   
    console.log('WebSocket open');   //成功连接上Websocket
};

# 3. 当 ws 连接接收到数据时触发
ws.onmessage = function (e) {
   
    console.log('message: ' + e.data);  //打印出服务端返回过来的数据
};

# 4. 当 ws 连接发生通信错误时触发
ws.onerror = function () {
   
    console.log('连接出错');
};

# 5. 当连接关闭时触发
ws.onclose = function(){
   
    console.log('连接关闭')
}
复制代码
   

2)方法:

  • ws.send(str) // 通过ws连接发送数据
  • ws.close() // 关闭ws连接

django+webSocket通信:

 在urls.py里
from django.conf.urls import url
from django.contrib import admin
from app01 import views as v

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^index/', v.index),
    url(r'^echo$', v.echo),
]

在views.py里
from django.shortcuts import render
from dwebsocket.decorators import accept_websocket,require_websocket
from django.http import HttpResponse


def index(request):
    return render(request, 'index.html')

from dwebsocket.backends.default.websocket import DefaultWebSocket  # request.websocket就是DefaultWebSocket对象

tmp = []
# 只有加了这个装饰器,这个视图函数才能处理websocket请求
@accept_websocket
def echo(request):
    if not request.is_websocket():  #判断是不是websocket连接
        try:  #如果是普通的http方法
            message = request.GET['message']
            return HttpResponse(message)
        except:
            return render(request,'index.html')
    else:
        '''1.实现消息推送'''
        tmp.append(request.websocket)  # 把所有连接的websocket连接都加入列表中
        #  request.websocket = <dwebsocket.backends.default.websocket.DefaultWebSocket object at 0x00000272E69A4320>
        # failed:Invalid frame header:你的视图没有阻塞,请求过一次后服务器端就关闭连接了
        # 所以使用for循环 request.websocket 对象就会调用 __iter__()方法,利用迭代器进行阻塞
        for mess
在 React Native 中使用 WebSocket,可以使用内置的 `WebSocket` API。要实现心跳检测和重新连接机制,可以编写自定义的 WebSocket 类。 下面是一个简单的实现,可以用作参考: ```javascript class MyWebSocket { constructor(url) { this.ws = new WebSocket(url); this.heartBeatTimer = null; this.reconnectTimer = null; this.isClosed = false; this.ws.onopen = () => { this.heartBeat(); }; this.ws.onmessage = (event) => { // 处理收到的消息 }; this.ws.onerror = (error) => { console.log(`WebSocket error: ${error}`); this.reconnect(); }; this.ws.onclose = () => { console.log(`WebSocket closed`); this.isClosed = true; this.reconnect(); }; } send(data) { if (!this.isClosed) { this.ws.send(data); } } heartBeat() { this.send('heart beat'); this.heartBeatTimer = setTimeout(() => { this.heartBeat(); }, 10000); // 10秒检测一次心跳 } reconnect() { if (this.isClosed) { return; } if (this.reconnectTimer) { clearTimeout(this.reconnectTimer); } this.reconnectTimer = setTimeout(() => { console.log(`WebSocket reconnecting...`); this.ws = new WebSocket(this.ws.url); this.ws.onopen = () => { console.log(`WebSocket reconnected`); clearTimeout(this.reconnectTimer); this.isClosed = false; this.heartBeat(); }; this.ws.onmessage = (event) => { // 处理收到的消息 }; this.ws.onerror = (error) => { console.log(`WebSocket error: ${error}`); this.reconnect(); }; this.ws.onclose = () => { console.log(`WebSocket closed`); this.isClosed = true; this.reconnect(); }; }, 3000); // 3秒后尝试重新连接 } close() { this.isClosed = true; clearTimeout(this.heartBeatTimer); clearTimeout(this.reconnectTimer); this.ws.close(); } } ``` 这个自定义的 WebSocket 类具有心跳检测和重新连接机制。在初始化时,会创建一个 WebSocket 连接,并设置 `onopen`、`onmessage`、`onerror` 和 `onclose` 事件的回调函数。当连接打开时,会开始心跳检测;当连接关闭时,会尝试重新连接。在发送消息时,会检查连接是否已关闭,如果未关闭,则发送消息。关闭连接时,会清除定时器并关闭 WebSocket 连接。 使用这个自定义的 WebSocket 类时,只需实例化它,并调用其 `send` 方法发送消息: ```javascript const ws = new MyWebSocket('ws://localhost:8080'); ws.send('hello'); ``` 也可以在需要时关闭连接: ```javascript ws.close(); ``` 这样就可以在 React Native 中使用 WebSocket,并实现心跳检测和重新连接机制了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值