一、开发工具
1.后端开发工具
python 3.12.0 + Django 5.0.3 + PyCharm 2023.2.5社区版
2.前端开发工具
HBuilder X 4.06 + Vue3
二、后端开发
1.创建django项目
创建 django 项目参考我的另一篇 PyCharm社区版创建Django基于DRF的纯后端项目 ,
2.打开项目并创建 ws 应用
通过社区版 pycharm 打开 wsmanage 目录并配置好虚拟环境,在终端中敲入 python manage.py startapp ws 并回车创建 ws 应用
3.安装 channels 和它的依赖库 daphne
虚拟环境安装用于 web socket 通过的 channels 模块,django4 以上的版本 channels 需要依赖daphne模块,用以下命令进行安装
pip install channels[daphne]
4.注册应用和 channels
在 settings.py 的 INSTALLED_APPS 中添加 daphne 、 ws.apps.WsConfig 和 channels 模块
5.添加异步定义
在 settings.py 中的 WSGI_APPLICATION 的下面添加 ASGI_APPLICATION 定义
WSGI_APPLICATION = 'wsmanage.wsgi.application'
ASGI_APPLICATION = 'wsmanage.asgi.application'
6.添加自定义 consumer 实现 websocket 收发
在 ws 应用目录创建 consumers.py 文件,内容如下
from channels.generic.websocket import WebsocketConsumer
import json
class Cons(WebsocketConsumer):
def connect(self): # 定义产生连接时的回调函数
print('新的连接')
self.accept() #同意连接
def disconnect(self, code): # 定义断开时的回调函数
print('连接已经断开',code)
def receive(self, text_data=None, bytes_data=None):
print(text_data, bytes_data)
self.send('from channels:'+text_data)
7.添加异步路由
在 settings.py 同级目录中创建 routings.py 文件,内容如下
from django.urls import path
from ws import consumers
websocket_urlpatterns = [
path('message/', consumers.Cons.as_asgi()),
]
8.修改异步文件 asgi.py
修改 settings.py 同级目录中的 asgi.py 文件定义异步调用,asgi.py文件内容修改后如下:
import os
from django.core.asgi import get_asgi_application
from channels.routing import ProtocolTypeRouter, URLRouter
from wsmanage import routings # 自定义的路由
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'wsmanage.settings')
# application = get_asgi_application() # 注释掉这行,改为 http 和 websocket 同时使用
application = ProtocolTypeRouter({
'http': get_asgi_application(), # http 访问时,使用默认路由
'websocket': URLRouter(routings.websocket_urlpatterns), # websocket 访问时,使用自定义路由
})
9.运行项目
在终端输入 python manage.py runserver 启动项目
10.测试websocket
websocket 测试的在线工具挺多,比如 ws在线测试
三、前端开发
1.创建项目
在 HBuilder X 中新建 uni-app 项目
2.页面布局
2.撸代码
修改项目下 pages/index/ 下的 index.vue 文件如下
<template>
<view class="content">
<input type="text" class="sendframe" v-model="sendmessage" placeholder="发送的数据">
<button class="sendbtn" @click="sendbtn">发送</button>
<text class="recvframe">{{recvmessage}}</text>
</view>
</template>
<script>
export default {
data() {
return {
recvmessage: '',
sendmessage: '',
ws: null
}
},
onLoad() {
this.ws = uni.connectSocket({
url: 'ws://127.0.0.1:8000/message/',
success: (res) => {
this.recvmessage += '\r\nwebsocket已连接';
},
fail: (err) => {
this.recvmessage += '\r\nwebsocket连接失败';
}
});
this.ws.onOpen((res) => {
this.recvmessage += '\r\nwebsocket连接正常打开';
});
this.ws.onClose((res) => {
this.recvmessage += '\r\nsebsocket已关闭';
});
this.ws.onMessage((res) => {
this.recvmessage += '\r\n' + res.data;
});
},
methods: {
sendbtn() {
this.ws.send({
data: this.sendmessage,
})
}
}
}
</script>
<style lang="scss">
.content {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 10rpx;
.sendframe {
width: 500rpx;
height: 60rpx;
border: 1rpx solid black;
border-radius: 10rpx;
padding: 10rpx;
}
.sendbtn {
width: 520rpx;
font-size: 26rpx;
background: radial-gradient(lightcyan, gray);
color: red;
margin: 10rpx;
}
.recvframe {
width: 500rpx;
height: 300rpx;
border: 1rpx solid black;
border-radius: 10rpx;
padding: 10rpx;
}
}
</style>
3.运行前端代码
点击 HBuilder X 右上角的【预览】按钮运行项目,可以看到我们能进行 socket 收发了