WebSocket长连接

1、概述

1.1 定义

1.2 原理

2、Django中配置WebSocket

2.1安装第三方法包

    1. pip install channels

2.2 Django 中的配置

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

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

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

2.3 django中需要了解的

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

  • 基于asgi/channels启动

3、聊天室

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

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

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

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

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

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

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

3.2 前端补充回调函数

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

3.3 关闭连接

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

3.4 整合代码示例

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

  • 方法一
    1. <template>
    2. <div class="test">
    3. </div>
    4. </template>
    5. <script>
    6. export default {
    7. name : 'test',
    8. data() {
    9. return {
    10. websock: null,
    11. }
    12. },
    13. created() {
    14. this.initWebSocket();
    15. },
    16. destroyed() {
    17. this.websock.close() //离开路由之后断开websocket连接
    18. },
    19. methods: {
    20. initWebSocket(){ //初始化weosocket
    21. if()
    22. const wsuri = "ws://127.0.0.1:8080";
    23. this.websock = new WebSocket(wsuri);
    24. this.websock.onmessage = this.websocketonmessage;
    25. this.websock.onopen = this.websocketonopen;
    26. this.websock.onerror = this.websocketonerror;
    27. this.websock.onclose = this.websocketclose;
    28. },
    29. websocketonopen(){ //连接建立之后执行send方法发送数据
    30. let actions = {"test":"12345"};
    31. this.websocketsend(JSON.stringify(actions));
    32. },
    33. websocketonerror(){//连接建立失败重连
    34. this.initWebSocket();
    35. },
    36. websocketonmessage(e){ //数据接收
    37. const redata = JSON.parse(e.data);
    38. },
    39. websocketsend(Data){//数据发送
    40. this.websock.send(Data);
    41. },
    42. websocketclose(e){ //关闭
    43. console.log('断开连接',e);
    44. },
    45. },
    46. }
    47. </script>
    48. <style lang='less'>
    49. </style>
  • 方法二
    1. <template>
    2. <div>
    3. <button @click="send">发消息</button>
    4. </div>
    5. </template>
    6. <script>
    7. export default {
    8. data () {
    9. return {
    10. path:"ws://192.168.0.200:8005/qrCodePage/ID=1/refreshTime=5",
    11. socket:""
    12. }
    13. },
    14. mounted () {
    15. // 初始化
    16. this.init()
    17. },
    18. methods: {
    19. init: function () {
    20. if(typeof(WebSocket) === "undefined"){
    21. alert("您的浏览器不支持socket")
    22. }else{
    23. // 实例化socket
    24. this.socket = new WebSocket(this.path)
    25. // 监听socket连接
    26. this.socket.onopen = this.open
    27. // 监听socket错误信息
    28. this.socket.onerror = this.error
    29. // 监听socket消息
    30. this.socket.onmessage = this.getMessage
    31. }
    32. },
    33. open: function () {
    34. console.log("socket连接成功")
    35. },
    36. error: function () {
    37. console.log("连接错误")
    38. },
    39. getMessage: function (msg) {
    40. console.log(msg.data)
    41. },
    42. send: function () {
    43. this.socket.send(params)
    44. },
    45. close: function () {
    46. console.log("socket已经关闭")
    47. }
    48. },
    49. destroyed () {
    50. // 销毁监听
    51. this.socket.onclose = this.close
    52. }
    53. }
    54. </script>
    55. <style>
    56. </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. Python中的魔术方法

    什么是魔术方法? 在Python中,所有用"__"包起来的方法,都称为[魔术方法]. 魔术方法一般是为了让显示器调用的,你自己并不需要调用它们. __init__:初始化函数 这个 ...

  2. ApacheCN 深度学习译文集 20201218 更新

    新增了四个教程: Python 人工智能中文版 0 前言 1 人工智能简介 2 人工智能的基本用例 3 机器学习管道 4 特征选择和特征工程 5 使用监督学习的分类和回归 6 集成学习的预测分析 7 ...

  3. springboot+atomikos+druid 数据库连接失效分析

    一.起因 最近查看系统的后台日志,经常发现这样的报错信息:The last package successfully received from the server was 40802382 mil ...

  4. ARC084F - XorShift

    有两种解法,这里都放一下. 解法一 首先易知异或运算可以视作是 \(\mathbb{F}_2\) 意义下的每一位独立的加法. 因此我们可以考虑对于每个二进制数 \(s\) 构造一个多项式 \(F(x) ...

  5. JspSmartUpload 简略使用

    JspSmartUpload 简略中文API文档 链接:https://blog.csdn.net/weixin_43670802/article/details/105143830 PDF课件 链接 ...

  6. bom-删除提示

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. 抓包神器 tcpdump 使用介绍 (转)

    tcpdump 命令使用简介 简单介绍 tcpdump 是一款强大的网络抓包工具,运行在 linux 平台上.熟悉 tcpdump 的使用能够帮助你分析.调试网络数据. 要想使用很好地掌握 tcpdu ...

  8. chmod以数字形式改变文件权限

    Linux文件的三种身份和四种权限,三种身份分别为: u:文件的拥有者 g:文件所属的群组 o:其他用户 对于每个身份,又有四种权限,分别为: r:读取文件的权限(read) w:写入文件的权限(wr ...

  9. 《Effective Python》笔记——第4章 元类及属性

    一.用属性取代get和set方法 常规的get和set方法如下: class OldResistor(): def __init__(self, ohms): self.__ohms = ohms d ...

  10. Spark RDD学习

    RDD(弹性分布式数据集)是Spark的核心抽象.它是一组元素,在集群的节点之间进行分区,以便我们可以对其执行各种并行操作. 创建RDD的两种方式: 并行化驱动程序中的现有数据: 引用外部存储系统中的 ...