WebSocket长连接

1、概述

1.1 定义

1.2 原理

2、Django中配置WebSocket

2.1安装第三方法包

  • pip install channels

2.2 Django 中的配置

  • Settings中的配置
    INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'app01.apps.App01Config',
    'channels',#注册APP
    ]
  • 添加配置
    • 定位到Django3中的asgi.py下的application
    ASGI_APPLICATION = "djangoWS.asgi.application"
    • 修改asgy.py文件
    • 默认只支持http协议,修改其内容使得即支持HTTP又要支持WebSocket;
    import os
    
    from django.core.asgi import get_asgi_application
    from channels.routing import ProtocolTypeRouter,URLRouter
    from . import routing os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'djangoWS.settings')
    # 默认只支持http请求
    # application = get_asgi_application() application=ProtocolTypeRouter({
    "http":get_asgi_application(),
    "websocket":URLRouter(routing.websocket_urlpatterns),
    })
  • Settings.py的同级目录下,创建routing.py;

    # -*- coding: utf-8 -*-
    '''
    @Time : 2021/11/12 9:00
    @Author : ziqingbaojian
    @File : routing.py
    ''' from django.urls import re_path
    from app01 import consumers websocket_urlpatterns=[
    re_path(r'ws/?P<group>\w+/$',consumers.ShowNum.as_asgi())
    ]
  • app01下创建consumers.py,编写处理事务的逻辑。

    # -*- coding: utf-8 -*-
    '''
    @Time : 2021/11/12 9:11
    @Author : ziqingbaojian
    @File : consumers.py
    '''
    from channels.generic.websocket import WebsocketConsumer
    from channels.exceptions import StopConsumer # 继承WebsocketConsumer
    class ShowNum(WebsocketConsumer):
    def websocket_connect(self, message):
    # 有客户端来向后端发送WebSocket连接请求时,自动触发
    # 允许客户端的连接
    self.accept()
    # raise StopConsumer()# 不创建连接,直接使用raise将异常抛出; def websocket_receive(self, message):
    # 基于WebSocket想后端发送数据,自动触发接收数据
    # 接收到前端传回的消息
    self.send("不要回答,不要回答,不要回答") def websocket_disconnect(self, message):
    # 客户端与服务端断开连接时,自动触发
    raise StopConsumer()

2.3 django中需要了解的

  • wsgi:django3以前django属于同步的,wsgi是处理Socket
  • asgi : 相当于wsgi+异步+WebSocket
  • 普通启动,默认使用的是wsgi**

  • 基于asgi/channels启动

3、聊天室

  • 访问到地址界面,http请求

  • 让客户端向服务端主动发送websocket连接,服务端收到连接后(握手)。

    • 前端
    //websocket的协议,发送数据要带ws相当于,http请求以http开头一样;
    socket= new WebSocket("ws://127.0.0.1:8001/ws/123/")
    • 服务端
    from channels.generic.websocket import WebsocketConsumer
    from channels.exceptions import StopConsumer # 继承WebsocketConsumer
    class ShowNum(WebsocketConsumer):
    def websocket_connect(self, message):
    # 有客户端来向后端发送WebSocket连接请求时,自动触发
    # 允许客户端的连接(握手)
    print("连接来拉")
    self.accept()
    '''两次请求,连接一次握手一次'''
    # raise StopConsumer()# 不创建连接,直接使用raise将异常抛出;

3.1 收发消息( 客户端-->服务端)

  • 客户端
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
    .top{
    height: 300px;
    width: 100%;
    border: 1px solid #ddd;
    }
    </style>
    </head>
    <body>
    <div class="top"></div>
    <input type="text" placeholder="请输入" id="txt">
    <button onclick="sendMessage()">发送</button>
    <script>
    //websocket的协议,发送数据要带ws相当于,http请求以http开头一样;
    socket= new WebSocket("ws://127.0.0.1:8001/ws/123/")
    function sendMessage(){
    var tag=document.getElementById("txt");
    socket.send(tag.value);
    }
    </script>
    </body>
    </html>
  • 服务端
    # -*- coding: utf-8 -*-
    '''
    @Time : 2021/11/12 9:11
    @Author : ziqingbaojian
    @File : consumers.py
    '''
    from channels.generic.websocket import WebsocketConsumer
    from channels.exceptions import StopConsumer # 继承WebsocketConsumer
    class ShowNum(WebsocketConsumer): def websocket_receive(self, message):
    # 基于WebSocket想后端发送数据,自动触发接收数据
    # 接收到前端传回的消息
    print(message)
    self.send("不要回答,不要回答,不要回答")

3.2 收发消息(服务端-->客户端)

  • 服务端
    from channels.generic.websocket import WebsocketConsumer
    from channels.exceptions import StopConsumer # 继承WebsocketConsumer
    class ShowNum(WebsocketConsumer):
    def websocket_connect(self, message):
    # 有客户端来向后端发送WebSocket连接请求时,自动触发
    # 允许客户端的连接(握手)
    print("连接来拉")
    self.accept()
    '''两次请求,连接一次握手一次'''
    # raise StopConsumer()# 不创建连接,直接使用raise将异常抛出;
    # 服务端给客户端发送消息
    self.send("来了呀,哈哈哈")
  • 客户端
    <script>
    //websocket的协议,发送数据要带ws相当于,http请求以http开头一样;
    socket= new WebSocket("ws://127.0.0.1:8001/ws/123/")
    function sendMessage(){
    var tag=document.getElementById("txt");
    socket.send(tag.value);
    }
    //当websocket接收到服务端发送来的消息的时候会自动触发这个函数
    socket.onmessage=function (event){
    console.log(event.data)
    } </script>

3.2 前端补充回调函数

<script>
//创建好连接之后自动触发(服务端执行完(self.accpet()之后会立即执行)
socket.onopen=function(event){
let tag= document.createElement("div");
tag.innerText="连接成功";
document.getElementById("top").appendChild(tag);
}
//连接成功之后进行提示
</script>

3.3 关闭连接

  • 客户端主动关闭
    • 客户端
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
    .top{
    height: 300px;
    width: 100%;
    border: 1px solid #ddd;
    }
    </style>
    </head>
    <body>
    <div class="top"></div>
    <input type="text" placeholder="请输入" id="txt">
    <button onclick="sendMessage()">发送</button>
    <button onclick="closeConn()">关闭连接</button> <script>
    //websocket的协议,发送数据要带ws相当于,http请求以http开头一样;
    socket= new WebSocket("ws://127.0.0.1:8001/ws/123/")
    function sendMessage(){
    var tag=document.getElementById("txt");
    socket.send(tag.value);
    } //当websocket接收到服务端发送来的消息的时候会自动触发这个函数
    socket.onmessage=function (event){
    console.log(event.data)
    }
    function closeConn(){
    socket.close();//向服务端发送断开连接的请求
    }
    </script>
    </body>
    </html>
    • 服务端
    # -*- coding: utf-8 -*-
    from channels.generic.websocket import WebsocketConsumer
    from channels.exceptions import StopConsumer # 继承WebsocketConsumer
    class ShowNum(WebsocketConsumer): def websocket_disconnect(self, message):
    # 客户端与服务端断开连接时,自动触发
    print("断开连接了")
    raise StopConsumer()
  • 服务端主动关闭连接
    • 服务端
    from channels.generic.websocket import WebsocketConsumer
    from channels.exceptions import StopConsumer # 继承WebsocketConsumer
    class ShowNum(WebsocketConsumer): def websocket_receive(self, message):
    # 基于WebSocket想后端发送数据,自动触发接收数据
    # 接收到前端传回的消息
    print(message)
    text=message['text']
    print(text)
    self.send("不要回答,不要回答,不要回答")
    if text=="close":
    # 法一
    self.close()# 会触发前端的onCllose方法;
    return # 不在执行后期的代码
    # 法二
    # raise StopConsumer()# 如果服务端断开连接时,执行了StopConsumer异常,那么websocket_disconnect方法不在执行;
    • 客户端
    <script>
    //websocket的协议,发送数据要带ws相当于,http请求以http开头一样;
    socket= new WebSocket("ws://127.0.0.1:8001/ws/123/")
    function sendMessage(){
    var tag=document.getElementById("txt");
    socket.send(tag.value);
    }
    //服务端主动断开连接的时候会被触发
    socket.onclose=function (event){
    console.log("连接已断开")
    }
    </script>

3.4 整合代码示例

  • 服务端
    from channels.generic.websocket import WebsocketConsumer
    from channels.exceptions import StopConsumer # 继承WebsocketConsumer
    class ShowNum(WebsocketConsumer):
    def websocket_connect(self, message):
    # 有客户端来向后端发送WebSocket连接请求时,自动触发
    # 允许客户端的连接(握手)
    print("连接来拉")
    self.accept()
    '''两次请求,连接一次握手一次'''
    # raise StopConsumer()# 不创建连接,直接使用raise将异常抛出;
    # 服务端给客户端发送消息
    self.send("来了呀,哈哈哈") def websocket_receive(self, message):
    # 基于WebSocket想后端发送数据,自动触发接收数据
    # 接收到前端传回的消息
    print(message)
    text=message['text']
    print(text)
    self.send("不要回答,不要回答,不要回答")
    if text=="close":
    # 法一
    self.close()# 会触发前端的onCllose方法;
    return # 不在执行后期的代码
    # 法二
    # raise StopConsumer()# 如果服务端断开连接时,执行了StopConsumer异常,那么websocket_disconnect方法不在执行;
    def websocket_disconnect(self, message):
    # 客户端与服务端断开连接时,自动触发,包括关闭页面与浏览器的情况
    print("断开连接了")
    raise StopConsumer()
  • 客户端
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
    .top{
    height: 300px;
    width: 100%;
    border: 1px solid #ddd;
    }
    </style>
    </head>
    <body>
    <div class="top"></div>
    <input type="text" placeholder="请输入" id="txt">
    <button onclick="sendMessage()">发送</button>
    <button onclick="closeConn()">关闭连接</button>
    <script>
    //websocket的协议,发送数据要带ws相当于,http请求以http开头一样;
    socket= new WebSocket("ws://127.0.0.1:8001/ws/123/")
    function sendMessage(){
    var tag=document.getElementById("txt");
    socket.send(tag.value);
    }
    //服务端主动断开连接的时候会被触发
    socket.onclose=function (event){
    console.log("连接已断开")
    } //当websocket接收到服务端发送来的消息的时候会自动触发这个函数
    socket.onmessage=function (event){
    console.log(event.data)
    }
    function closeConn(){
    socket.close();//向服务端发送断开连的请求
    }
    </script>
    </body>
    </html>

3.5 群聊功能

  • 配置django中的配置文件或者,自定义设置连接池

4 、vue中使用Webscoket

  • 参考文献1:https://www.cnblogs.com/niuben/p/14607900.html

  • 参考文献2 :https://www.cnblogs.com/qisi007/p/10213886.html

  • 方法一
    <template>
    <div class="test"> </div>
    </template> <script>
    export default {
    name : 'test',
    data() {
    return {
    websock: null,
    }
    },
    created() {
    this.initWebSocket();
    },
    destroyed() {
    this.websock.close() //离开路由之后断开websocket连接
    },
    methods: {
    initWebSocket(){ //初始化weosocket
    if()
    const wsuri = "ws://127.0.0.1:8080";
    this.websock = new WebSocket(wsuri);
    this.websock.onmessage = this.websocketonmessage;
    this.websock.onopen = this.websocketonopen;
    this.websock.onerror = this.websocketonerror;
    this.websock.onclose = this.websocketclose;
    },
    websocketonopen(){ //连接建立之后执行send方法发送数据
    let actions = {"test":"12345"};
    this.websocketsend(JSON.stringify(actions));
    },
    websocketonerror(){//连接建立失败重连
    this.initWebSocket();
    },
    websocketonmessage(e){ //数据接收
    const redata = JSON.parse(e.data);
    },
    websocketsend(Data){//数据发送
    this.websock.send(Data);
    },
    websocketclose(e){ //关闭
    console.log('断开连接',e);
    },
    },
    }
    </script>
    <style lang='less'> </style>
  • 方法二
    <template>
    <div>
    <button @click="send">发消息</button>
    </div>
    </template> <script>
    export default {
    data () {
    return {
    path:"ws://192.168.0.200:8005/qrCodePage/ID=1/refreshTime=5",
    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 () {
    this.socket.send(params)
    },
    close: function () {
    console.log("socket已经关闭")
    }
    },
    destroyed () {
    // 销毁监听
    this.socket.onclose = this.close
    }
    }
    </script> <style> </style>

WebSocket长连接的更多相关文章

  1. 当web应用包含了websocket长连接,如何在web应用前加一层nginx转发

    1 通过在web应用的前面加一层nginx ,可以实现一台主机部署多个应用,每个应用都可以用不同的域名去访问,并且端口都是80 2 nignx 转发websocket长连接 1 每个web应用,他们运 ...

  2. 实现单台测试机6万websocket长连接

    本文由作者郑银燕授权网易云社区发布. 本文是我在测试过程中的记录,实现了单台测试机发起最大的websocket长连接数.在一台测试机上,连接到一个远程服务时的本地端口是有限的.根据TCP/IP协议,由 ...

  3. Spring+Stomp+ActiveMq实现websocket长连接

    stomp.js+spring+sockjs+activemq实现websocket长连接,使用java配置. pom.xml(只列出除了spring基本依赖意外的依赖,spring-version为 ...

  4. Python WebSocket长连接心跳与短连接

    python websocket 安装 pip install websocket-client 先来看一下,长连接调用方式: ws = websocket.WebSocketApp("ws ...

  5. WebSocket 长连接 及超时问题解决

    <?phpset_time_limit(0); class SocketService { private $address = 'localhost'; private $port = 80; ...

  6. 雨露均沾的OkHttp—WebSocket长连接的使用&源码解析

    前言 最近老板又来新需求了,要做一个物联网相关的app,其中有个需求是客户端需要收发服务器不定期发出的消息. 内心OS:

  7. Django websocket 长连接使用

    下载  pip install dwebsocket WebSocket是一种在单个TCP连接上进行全双工通信的协议 WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客 ...

  8. 微信小程序 实现websocket长连接 以及断开连接之后自动重连

    app.js let socketMsgQueue = [] let isLoading = false App({ globalData: { userInfo: null, localSocket ...

  9. Browser 與 Server 持續同步的作法介紹 (Polling, Comet, Long Polling, WebSocket)长连接

    對 Comet 的懵懂 記得兩年多前,第一次看到 Gmail 中的 GTalk 覺得很好奇:「咦?線上聊天且是 Google 的熱門系統,只用傳統的 AJAX 應該會操爆伺服器吧?」很幸運的,當時前公 ...

随机推荐

  1. SpringBoot整合Nacos自动刷新配置

    目的 Nacos作为SpringBoot服务的注册中心和配置中心. 在NacosServer中修改配置文件,在SpringBoot不重启的情况下,获取到修改的内容. 本例将在配置文件中配置一个 cml ...

  2. __rept__和__str__

    最近一下子学了很多的知识点,导致我有点没反应过来,粗略的在草稿纸记了点自己的想法,趁休息的时间将它敲到博客里面去,免得丢失,这一篇写的挺废话的,有点啰嗦,本篇的重点是第二段程序后开始的总结和后面的几个 ...

  3. react 没有嵌套关系的组件通讯

    前提准备四个文件,两个子组件:List.List2和一个events.js文件以及一个App.js父组件; 在src目录下创建events.js,里面的内容如下: // events.js(以常用的发 ...

  4. Android 关于Intent的一些简略总结

    感谢大佬:https://www.jianshu.com/p/19147a69e970 Intent 常用构造方法: | 方法 | 描述 | |Intent() | 构造一个空 Intent | | ...

  5. Shell中的变量替换

    ${str-newStr} 仅当str为null的时候替换 ${str:-newStr} 当str为null或者str为空字符串的时候替换 综上,-号,当str没有内容,则替换, :号只是增加了空字符 ...

  6. Mac 屏幕录制Gif 制作 By-胡罗

    一.视频录制 1)使用Mac系统自带的QuickTime进行屏幕录像 手动打开(如下图) 详细 Mac 基础教程:如何使用 Mac 系统原生的屏幕录制功能 相关快捷键 option+command+n ...

  7. HGAME第一二周re

    RE easyasm 有手就行 高低位互换再异或0x17 a = [0x91, 0x61, 0x01, 0xC1, 0x41, 0xA0, 0x60, 0x41, 0xD1, 0x21, 0x14, ...

  8. python迭代器对象及异常处理

    内容概要 内置函数(可与匿名函数一起使用) 可迭代对象 迭代器对象 for循环内部原理 异常处理 内容详细 一.内置函数 # 1. map() 映射 l1 = [1, 3, 5, 7, 9] res ...

  9. Solution -「洛谷 P4372」Out of Sorts P

    \(\mathcal{Description}\)   OurOJ & 洛谷 P4372(几乎一致)   设计一个排序算法,设现在对 \(\{a_n\}\) 中 \([l,r]\) 内的元素排 ...

  10. Solution -「Gym 102759C」Economic One-way Roads

    \(\mathcal{Description}\)   Link.   给定一个含 \(n\) 个点 \(m\) 条边的简单无向图,每条边的两种定向方法各有权值,求使得图强连通且定向权值和最小的方法. ...