WebSocket长连接
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
方法一
<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长连接的更多相关文章
- 当web应用包含了websocket长连接,如何在web应用前加一层nginx转发
1 通过在web应用的前面加一层nginx ,可以实现一台主机部署多个应用,每个应用都可以用不同的域名去访问,并且端口都是80 2 nignx 转发websocket长连接 1 每个web应用,他们运 ...
- 实现单台测试机6万websocket长连接
本文由作者郑银燕授权网易云社区发布. 本文是我在测试过程中的记录,实现了单台测试机发起最大的websocket长连接数.在一台测试机上,连接到一个远程服务时的本地端口是有限的.根据TCP/IP协议,由 ...
- Spring+Stomp+ActiveMq实现websocket长连接
stomp.js+spring+sockjs+activemq实现websocket长连接,使用java配置. pom.xml(只列出除了spring基本依赖意外的依赖,spring-version为 ...
- Python WebSocket长连接心跳与短连接
python websocket 安装 pip install websocket-client 先来看一下,长连接调用方式: ws = websocket.WebSocketApp("ws ...
- WebSocket 长连接 及超时问题解决
<?phpset_time_limit(0); class SocketService { private $address = 'localhost'; private $port = 80; ...
- 雨露均沾的OkHttp—WebSocket长连接的使用&源码解析
前言 最近老板又来新需求了,要做一个物联网相关的app,其中有个需求是客户端需要收发服务器不定期发出的消息. 内心OS:
- Django websocket 长连接使用
下载 pip install dwebsocket WebSocket是一种在单个TCP连接上进行全双工通信的协议 WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客 ...
- 微信小程序 实现websocket长连接 以及断开连接之后自动重连
app.js let socketMsgQueue = [] let isLoading = false App({ globalData: { userInfo: null, localSocket ...
- Browser 與 Server 持續同步的作法介紹 (Polling, Comet, Long Polling, WebSocket)长连接
對 Comet 的懵懂 記得兩年多前,第一次看到 Gmail 中的 GTalk 覺得很好奇:「咦?線上聊天且是 Google 的熱門系統,只用傳統的 AJAX 應該會操爆伺服器吧?」很幸運的,當時前公 ...
随机推荐
- Html设置文本换行与不按行操作
图片来源:W3C 部分引自大佬:https://zhidao.baidu.com/question/424920602093167052.html 强制不换行 div{ white-space:now ...
- hitTest练习
业务逻辑1: 底部一个按钮, 按钮的上面有一个View,遮挡在按钮的上面. 点击View时, View接收事件,当发现点击的点在按钮的位置时, 让底部的按钮处理事件. ...
- js注释和数据类型转换
单行注释 用来描述下面一个或多行代码的作用 // 这是一个变量var name = 'hm'; 多行注释 用来注释多条代码 /*var age = 18;var name = 'zs';console ...
- 为 ubuntu 切换更新源
感谢大佬:https://blog.csdn.net/sudaning/article/details/83445677 目录 备份 修改源文件 更新列表 更新软件 备份 sudo cp /etc/a ...
- iOS 性能优化系列
Objective-C 高性能的循环 使用 Swift 和 Objective-C 执行 iOS 内存管理的 7 个简单技巧 @autoreleasepool-内存的分配与释放
- iOS 即使通讯第三方SDK 资料
第三方即时通讯SDK,下面是一些主流的第三方的即时通讯SDK,尽管不能查看里面的源代码,但通过查看头文件,能为实现自己的即使通讯SDK提供很好的思路.(备用) 容云 容联.云通讯 IMSDK - 轻松 ...
- 2.k8s的架构
之前了解了k8s到底是什么,接下来看看k8s的组成. 一.Kubernetes架构 学习k8s,最终目的是为了部署应用,部署一个完整的k8s, 就要知道k8s的组成.k8s主要包含两大部分: 中间包含 ...
- 快速搭建springboot工程
一.创建SpringBoot的三种方式 在线创建: https://start.spring.io 在IntelliJ IDEA中选择Spring Initializr创建:或者在Eclipse中选择 ...
- Ubuntu service 命令
启动指定服务 sudo service 服务名 start 停止指定服务 sudo service 服务名 stop 重启指定服务 sudo service 服务名 start 查看所有服务 sudo ...
- make小tip
总所周知make一般需要Makefile才能编译相关源码,但也可以无需Makefile就能编译一些简单的源代码. 在算法竞赛里,一道题的源程序一般只有一个文件,此时用Makefile显得十分累赘,但如 ...