• 06.websocket


    websocket:https://www.cnblogs.com/xiaonq/p/12238651.html

    webssh:https://www.cnblogs.com/xiaonq/p/12243024.html

    什么是websocket

    1、webSocket是一种在单个TCP连接上进行全双工通信的协议
    2、客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。
    3、浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输

    websocket与http区别

    1、http请求建立连接只能发送一次请求,不能有服务器端主动向客户端发送请求
    2、websocket建立的长连接,一次连接,后续一直通信,这样节省资源,可以有客户端发送请求给服务器端

    远古时期解决方案就是轮询

    1、客户端以设定的时间间隔周期性地向服务端发送请求,频繁地查询是否有新的数据改动(浪费流量和资源)

    webSocket应用场景?

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

    websocket原理

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

    websocket实现心跳检测的思路

    1、通过setInterval定时任务每个3秒钟调用一次reconnect函数
    2、reconnect会通过socket.readyState来判断这个websocket连接是否正常
    3、如果不正常就会触发定时连接,每4s钟重试一次,直到连接成功
    4、如果是网络断开的情况下,在指定的时间内服务器端并没有返回心跳响应消息,因此服务器端断开了。
    5、服务断开我们使用ws.close关闭连接,在一段时间后,可以通过 onclose事件监听到。

    实现聊天功能

    # 后端的django代码
    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 message in request.websocket:
                for ws in tmp:
                    ws.send(message)
    
            '''2.实现聊天室思路'''
            # d = {}                                # 使用了一个dict来保存数据,
            # d['zhangsan'] = request.websocket     # key值是用户身份,value值是dict类型的{username:websocket}。
            # d['zhangsan'].send(message)           # 发送消息到客户端
            # d['lisi'].send(message)   ==>  request.websocket.send(message)
    
            # 这只是个思路,如果正式使用的话,肯定会对group封装,也不会只保存在内存中,需要保存到redis中去
            # 并且对每个websocket对象设置有效期,过期清除,避免长期挂起状态消耗系统资源等
    # 前端VUE代码
    <template>
      <div>
        <button @click="send">发消息</button>
      </div>
    </template>
    
    <script>
      export default {
        data () {
          return {
            path:"ws://127.0.0.1:8000/echo?username=zhangsan&token=xxxx",
            socket:""
          }
        },
        mounted () {
          // 初始化
          this.init()
        },
        methods: {
          init: function () {
            if(typeof(WebSocket) === "undefined"){
              alert("您的浏览器不支持socket")
            }else{
              // 实例化socket
              this.socket = new WebSocket(this.path)
              // 监听socket连接
              this.socket.onopen = this.open
              // 监听socket错误信息
              this.socket.onerror = this.error
              // 监听socket消息
              this.socket.onmessage = this.getMessage
            }
          },
          open: function () {
            console.log("socket连接成功")
          },
          error: function () {
            console.log("连接错误")
          },
          getMessage: function (msg) {
            console.log(msg.data)         // 打印后台返回的数据
          },
          send: function () {
            var params = 'hahahahhahaha';
            this.socket.send(params)      // 发送给后台的数据
          },
          close: function () {
            console.log("socket已经关闭")
          }
        },
        destroyed () {
          // 销毁监听
          this.socket.onclose = this.close
        }
      }
    </script>
    
    <style>
    
    </style>
  • 相关阅读:
    注册表清理bat
    apache2.2.14 负载均衡过程中遇到问题记录;
    thikpad 中eclipse/idea 无法获取鼠标
    PLSQL DEVELOPER 提示(错误)信息是乱码;亲测有效
    windows右键 打开方式 浏览 无法添加默认打开方式 解决
    澳洲值得代购物品汇总
    5 open source dashboard tools for visualizing data
    nginx概述
    Linux bash 参数处理办法
    Linux shell 启动配置文件设置
  • 原文地址:https://www.cnblogs.com/xiaoxiamiaichiyu/p/14581487.html
Copyright © 2020-2023  润新知