WebSocket长连接
1、概述
1.1 定义
1.2 原理
2、Django中配置WebSocket
2.1安装第三方法包
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',
]
-
添加配置
- 定位到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')
application=ProtocolTypeRouter({
"http":get_asgi_application(),
"websocket":URLRouter(routing.websocket_urlpatterns),
})
-
在Settings.py的同级目录下,创建routing.py;
'''
@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,编写处理事务的逻辑。
'''
@Time : 2021/11/12 9:11
@Author : ziqingbaojian
@File : consumers.py
'''
from channels.generic.websocket import WebsocketConsumer
from channels.exceptions import StopConsumer
class ShowNum(WebsocketConsumer):
def websocket_connect(self, message):
self.accept()
def websocket_receive(self, message):
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连接,服务端收到连接后(握手)。
socket= new WebSocket("ws://127.0.0.1:8001/ws/123/")
from channels.generic.websocket import WebsocketConsumer
from channels.exceptions import StopConsumer
class ShowNum(WebsocketConsumer):
def websocket_connect(self, message):
print("连接来拉")
self.accept()
'''两次请求,连接一次握手一次'''
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>
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>
-
服务端
'''
@Time : 2021/11/12 9:11
@Author : ziqingbaojian
@File : consumers.py
'''
from channels.generic.websocket import WebsocketConsumer
from channels.exceptions import StopConsumer
class ShowNum(WebsocketConsumer):
def websocket_receive(self, message):
print(message)
self.send("不要回答,不要回答,不要回答")
3.2 收发消息(服务端–>客户端)
-
服务端 from channels.generic.websocket import WebsocketConsumer
from channels.exceptions import StopConsumer
class ShowNum(WebsocketConsumer):
def websocket_connect(self, message):
print("连接来拉")
self.accept()
'''两次请求,连接一次握手一次'''
self.send("来了呀,哈哈哈")
-
客户端 <script>
socket= new WebSocket("ws://127.0.0.1:8001/ws/123/")
function sendMessage(){
var tag=document.getElementById("txt");
socket.send(tag.value);
}
socket.onmessage=function (event){
console.log(event.data)
}
</script>
3.2 前端补充回调函数
<script>
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>
socket= new WebSocket("ws://127.0.0.1:8001/ws/123/")
function sendMessage(){
var tag=document.getElementById("txt");
socket.send(tag.value);
}
socket.onmessage=function (event){
console.log(event.data)
}
function closeConn(){
socket.close();
}
</script>
</body>
</html>
from channels.generic.websocket import WebsocketConsumer
from channels.exceptions import StopConsumer
class ShowNum(WebsocketConsumer):
def websocket_disconnect(self, message):
print("断开连接了")
raise StopConsumer()
-
服务端主动关闭连接
from channels.generic.websocket import WebsocketConsumer
from channels.exceptions import StopConsumer
class ShowNum(WebsocketConsumer):
def websocket_receive(self, message):
print(message)
text=message['text']
print(text)
self.send("不要回答,不要回答,不要回答")
if text=="close":
self.close()
return
<script>
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
class ShowNum(WebsocketConsumer):
def websocket_connect(self, message):
print("连接来拉")
self.accept()
'''两次请求,连接一次握手一次'''
self.send("来了呀,哈哈哈")
def websocket_receive(self, message):
print(message)
text=message['text']
print(text)
self.send("不要回答,不要回答,不要回答")
if text=="close":
self.close()
return
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>
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("连接已断开")
}
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>
|