Skip to content

Commit dee9747

Browse files
committed
改为同步模式
1 parent 10aae0e commit dee9747

20 files changed

+258
-29
lines changed

db.sqlite3

128 KB
Binary file not shown.
Binary file not shown.
Binary file not shown.
63 Bytes
Binary file not shown.
590 Bytes
Binary file not shown.

django3_websocket/routing.py

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# !/usr/bin/python3
2+
# -*- coding: utf-8 -*-
3+
from channels.auth import AuthMiddlewareStack
4+
from channels.routing import ProtocolTypeRouter, URLRouter
5+
import web.routing
6+
7+
application = ProtocolTypeRouter({
8+
# (http->django views is added by default)
9+
'websocket': AuthMiddlewareStack(
10+
URLRouter(
11+
web.routing.websocket_urlpatterns
12+
)
13+
),
14+
})

django3_websocket/settings.py

+18-1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
'django.contrib.messages',
3939
'django.contrib.staticfiles',
4040
'web.apps.WebConfig',
41+
'channels',
4142
]
4243

4344
MIDDLEWARE = [
@@ -119,4 +120,20 @@
119120
# Static files (CSS, JavaScript, Images)
120121
# https://docs.djangoproject.com/en/3.1/howto/static-files/
121122

122-
STATIC_URL = '/static/'
123+
STATIC_URL = '/static/'
124+
K8S_URL = "https://192.168.31.74:6443"
125+
ASGI_APPLICATION = 'django3_websocket.routing.application'
126+
# CHANNEL_LAYERS = {
127+
# 'default': {
128+
# 'BACKEND': 'channels_redis.core.RedisChannelLayer',
129+
# 'CONFIG': {
130+
# "hosts": [('192.168.31.196', 6379)],
131+
# },
132+
# },
133+
# }
134+
CHANNEL_LAYERS = {
135+
"default": {
136+
"BACKEND": "channels.layers.InMemoryChannelLayer",
137+
# "ROUTING": "channels_example.routing.channel_routing",
138+
}
139+
}

django3_websocket/urls.py

+1
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,6 @@
1919

2020
urlpatterns = [
2121
path('admin/', admin.site.urls),
22+
path('', views.index),
2223
path('index/', views.index),
2324
]

requirements.txt

-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
11
Django==3.1
22
channels==2.4.0
33
paramiko==2.7.2
4-
uvicorn==0.11.8

templates/chat/index.html

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8"/>
5+
<title>Chat Rooms</title>
6+
</head>
7+
<body>
8+
What chat room would you like to enter?<br>
9+
<input id="room-name-input" type="text" size="100"><br>
10+
<input id="room-name-submit" type="button" value="Enter">
11+
12+
<script>
13+
document.querySelector('#room-name-input').focus();
14+
document.querySelector('#room-name-input').onkeyup = function(e) {
15+
if (e.keyCode === 13) { // enter, return
16+
document.querySelector('#room-name-submit').click();
17+
}
18+
};
19+
20+
document.querySelector('#room-name-submit').onclick = function(e) {
21+
var roomName = document.querySelector('#room-name-input').value;
22+
window.location.pathname = '/chat/' + roomName + '/';
23+
};
24+
</script>
25+
</body>
26+
</html>

templates/chat/room.html

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<!-- chat/templates/chat/room.html -->
2+
<!DOCTYPE html>
3+
<html>
4+
<head>
5+
<meta charset="utf-8"/>
6+
<title>Chat Room</title>
7+
</head>
8+
<body>
9+
<textarea id="chat-log" cols="100" rows="20"></textarea><br>
10+
<input id="chat-message-input" type="text" size="100"><br>
11+
<input id="chat-message-submit" type="button" value="Send">
12+
{{ room_name|json_script:"room-name" }}
13+
<script>
14+
const roomName = JSON.parse(document.getElementById('room-name').textContent);
15+
16+
const chatSocket = new WebSocket(
17+
'ws://'
18+
+ window.location.host
19+
+ '/ws/chat/'
20+
+ roomName
21+
+ '/'
22+
);
23+
24+
chatSocket.onmessage = function(e) {
25+
//const data = JSON.parse(e.data);
26+
//document.querySelector('#chat-log').value += (data.message + '\n');
27+
//const data = JSON.parse(e.data);
28+
console.log("接收消息"+e.data);
29+
document.querySelector('#chat-log').value += (e.data + '\n');
30+
};
31+
32+
chatSocket.onclose = function(e) {
33+
console.error('Chat socket closed unexpectedly');
34+
};
35+
36+
document.querySelector('#chat-message-input').focus();
37+
document.querySelector('#chat-message-input').onkeyup = function(e) {
38+
if (e.keyCode === 13) { // enter, return
39+
document.querySelector('#chat-message-submit').click();
40+
}
41+
};
42+
43+
document.querySelector('#chat-message-submit').onclick = function(e) {
44+
const messageInputDom = document.querySelector('#chat-message-input');
45+
const message = messageInputDom.value;
46+
chatSocket.send(JSON.stringify({
47+
'message': message
48+
}));
49+
messageInputDom.value = '';
50+
};
51+
</script>
52+
</body>
53+
</html>

templates/index.html

+37-27
Original file line numberDiff line numberDiff line change
@@ -3,50 +3,60 @@
33
<head>
44
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
55
<title>测试demo</title>
6-
<style type="text/css">
7-
#execute_script {
8-
margin: 20px;
9-
height: 40px;
10-
background-color: #00ff00;
11-
}
12-
</style>
6+
<!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
7+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"
8+
integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
139
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
14-
1510
</head>
1611
<body>
1712

18-
<button type="button" id="execute_script" value="laying_eggs">执行Shell脚本</button>
19-
<h3 style="margin: 20px;">脚本执行结果:</h3>
20-
<div id="messagecontainer" style="margin: 20px;">
13+
<div class="container">
14+
<div style="height: 30px"></div>
15+
<button type="button" id="execute_script" class="btn btn-success">查看日志</button>
16+
17+
<h4>日志内容:</h4>
18+
<div style="height: 600px;overflow: auto;" id="content_logs">
19+
<div id="messagecontainer" style="font-size: 16px;background-color: black;color: white">
20+
</div>
21+
</div>
2122
</div>
22-
<hr/>
2323
</body>
2424
<script type="text/javascript">
25-
$(function () {
26-
27-
});
2825
// 点击按钮
2926
$('#execute_script').click(function () {
30-
// 打开一个 web socket
31-
var socket = new WebSocket("ws://" + window.location.host);
32-
console.log(socket);
27+
// 新建websocket连接
28+
const chatSocket = new WebSocket(
29+
'ws://'
30+
+ window.location.host
31+
+ '/ws/result/'
32+
);
33+
3334
// 连接建立成功事件
34-
socket.onopen = function () {
35+
chatSocket.onopen = function () {
3536
console.log('WebSocket open');
3637
//发送字符: laying_eggs到服务端
37-
socket.send('laying_eggs');
38+
chatSocket.send(JSON.stringify({
39+
'message': 'laying_eggs'
40+
}));
41+
console.log("发送完字符串laying_eggs");
3842
};
3943
// 接收消息事件
40-
socket.onmessage = function (e) {
41-
if (e.data.length > 0) {
42-
//打印服务端返回的数据
43-
console.log('message: ' + e.data);
44-
$('#messagecontainer').append(e.data + '<br/>');
45-
}
44+
chatSocket.onmessage = function (e) {
45+
{#if (e.data.length > 0) {#}
46+
//打印服务端返回的数据
47+
console.log('message: ' + e.data);
48+
// 转换为字符串,防止卡死testestt
49+
$('#messagecontainer').append(String(e.data) + '<br/>');
50+
//滚动条自动到最底部
51+
$("#content_logs").scrollTop($("#content_logs")[0].scrollHeight);
52+
{# }#}
4653
};
4754
// 关闭连接事件
48-
socket.onclose = function(e) {
55+
chatSocket.onclose = function (e) {
4956
console.log("connection closed (" + e.code + ")");
57+
chatSocket.send(JSON.stringify({
58+
'message': 'close'
59+
}));
5060
}
5161
});
5262
</script>
2.24 KB
Binary file not shown.
314 Bytes
Binary file not shown.

web/__pycache__/urls.cpython-37.pyc

282 Bytes
Binary file not shown.

web/__pycache__/views.cpython-37.pyc

49 Bytes
Binary file not shown.
57 Bytes
Binary file not shown.

web/consumers.py

+99
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
import json
2+
from channels.generic.websocket import AsyncWebsocketConsumer
3+
import paramiko
4+
from channels.generic.websocket import WebsocketConsumer, AsyncWebsocketConsumer
5+
from asgiref.sync import async_to_sync
6+
7+
# 同步方式,仅作示例,不使用
8+
class SyncConsumer(WebsocketConsumer):
9+
def connect(self):
10+
self.username = "xiao" # 临时固定用户名
11+
print('WebSocket建立连接:', self.username)
12+
# 直接从用户指定的通道名称构造通道组名称
13+
self.channel_group_name = 'msg_%s' % self.username
14+
15+
# 加入通道层
16+
# async_to_sync(…)包装器是必需的,因为ChatConsumer是同步WebsocketConsumer,但它调用的是异步通道层方法。(所有通道层方法都是异步的。)
17+
async_to_sync(self.channel_layer.group_add)(
18+
self.channel_group_name,
19+
self.channel_name
20+
)
21+
22+
# 接受WebSocket连接。
23+
self.accept()
24+
25+
async_to_sync(self.channel_layer.group_send)(
26+
self.channel_group_name,
27+
{
28+
'type': 'get_message',
29+
}
30+
)
31+
32+
def disconnect(self, close_code):
33+
print('WebSocket关闭连接')
34+
# 离开通道
35+
async_to_sync(self.channel_layer.group_discard)(
36+
self.channel_group_name,
37+
self.channel_name
38+
)
39+
40+
# 从WebSocket中接收消息
41+
def receive(self, text_data=None, bytes_data=None):
42+
print('WebSocket接收消息:', text_data,type(text_data))
43+
text_data_json = json.loads(text_data)
44+
message = text_data_json['message']
45+
# print("receive message",message,type(message))
46+
# 发送消息到通道
47+
async_to_sync(self.channel_layer.group_send)(
48+
self.channel_group_name,
49+
{
50+
'type': 'get_message',
51+
'message': message
52+
}
53+
)
54+
55+
# 从通道中接收消息
56+
def get_message(self, event):
57+
# print("event",event,type(event))
58+
if event.get('message'):
59+
message = event['message']
60+
# 判断消息
61+
if message == "close":
62+
# 关闭websocket连接
63+
self.disconnect(self.channel_group_name)
64+
print("前端关闭websocket连接")
65+
66+
# 判断消息,执行脚本
67+
if message == "laying_eggs":
68+
# 执行的命令或者脚本
69+
command = 'bash /opt/test.sh'
70+
71+
# 远程连接服务器
72+
hostname = '192.168.31.196'
73+
username = 'root'
74+
password = 'root'
75+
76+
ssh = paramiko.SSHClient()
77+
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
78+
ssh.connect(hostname=hostname, username=username, password=password)
79+
# 务必要加上get_pty=True,否则执行命令会没有权限
80+
stdin, stdout, stderr = ssh.exec_command(command, get_pty=True)
81+
# result = stdout.read()
82+
# 循环发送消息给前端页面
83+
while True:
84+
nextline = stdout.readline().strip() # 读取脚本输出内容
85+
# print(nextline.strip())
86+
87+
# 发送消息到客户端
88+
self.send(
89+
text_data=nextline
90+
)
91+
print("已发送消息:%s" % nextline)
92+
# 判断消息为空时,退出循环
93+
if not nextline:
94+
break
95+
96+
ssh.close() # 关闭ssh连接
97+
# 关闭websocket连接
98+
self.disconnect(self.channel_group_name)
99+
print("后端关闭websocket连接")
164 Bytes
Binary file not shown.

web/routing.py

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# !/usr/bin/python3
2+
# -*- coding: utf-8 -*-
3+
from django.urls import re_path,path
4+
5+
from . import consumers
6+
7+
websocket_urlpatterns = [
8+
# 前端请求websocket连接
9+
path('ws/result/', consumers.SyncConsumer),
10+
]

0 commit comments

Comments
 (0)