解决问题: 1、bottle版本支持 ajax 请求处理:发现最新的13好像是可以的 2、websocket 复用 web 服务端口:
操作步骤: 1、将下边 test.py test.html 两个文件放在一个目录下。 2、运行python test.py 3、浏览器打开地址 http://localhost:8080 4、打开浏览器调试工具。
数据 python test.py
import json
import time
from gevent import queue
from bottle import route, run, static_file, request, Bottle, abort
from gevent.pywsgi import WSGIServer
from geventwebsocket import WebSocketError
from geventwebsocket.handler import WebSocketHandler
class HTTP_APP(Bottle):
def __init__(self, user="admin", ip="127.0.0.1", port=8080):
"""
:param user:
:param ip: 服务地址
:param port: 服务端口
"""
Bottle.__init__(self)
self.ip = ip
self.port = port
self._testUsers = {}
def __del__(self):
try:
if self.server != None:
self.server.close()
except:
pass
def start_server(self):
"""
启动websocket 服务
:return:
"""
self.server = WSGIServer(("0.0.0.0", self.port), self, handler_class=WebSocketHandler)
self.server.serve_forever()
def close_server(self):
if self.server != None:
self.server.close()
self.server = None
def register_http(self):
"""
web 服务注册
:return:
"""
@self.error(404)
def error404(error):
return u'404'
@self.route('/res/<resname:path>')
def res(resname):
"""
加载资源数据的路由
:param resname:
:return:
"""
return static_file(resname, root="./res")
@self.route('/')
def vote():
"""
主页面的路由
:return:
"""
return static_file("test.html", root="./")
@self.route('/api/<apiname>', method='POST')
def asyncApi(apiname):
print(apiname)
a = request
postdata =request.body.readline()
req_data = json.loads(postdata)
print("request: ", req_data)
res = {
"code" : 0,
"msg" : "",
"data" : []
}
if req_data["action"]=="get":pass
if req_data['action']=="add":
self._testUsers[req_data['user']]={
"user" : req_data['user'],
"ip" : "10.10.10.10",
"port" :req_data['port'],
"stopDate" : req_data['stopDate'],
"status" : False
}
if req_data['action'] =="del":
del self._testUsers[req_data['user']]
if req_data['action'] == "start":
self._testUsers[req_data['user']]["status"] = True
if req_data['action'] == "stop":
self._testUsers[req_data['user']]["status"] = False
res["data"] = [ v for k,v in self._testUsers.items() ]
r = json.dumps(res)
print("response:", res)
return res
@self.route('/ws')
def handle_websocket():
wsock = request.environ.get('wsgi.websocket')
clientid = wsock.handler.client_address[0]
if not wsock:
abort(400, 'Expected WebSocket request.')
while True:
try:
message = wsock.receive()
print("Your message was: %r" % message)
wsock.send("Your message was: %r" % message)
except WebSocketError:
break
http_server = HTTP_APP()
http_server.register_http()
http_server.start_server()
http test.html
<!DOCTYPE html>
<html style="height: 100%">
<head>
<meta charset="utf-8">
<link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.0.0-alpha1/css/bootstrap.min.css" rel="stylesheet">
</head>
<body style="height: 100%; margin: 0" onmousedown="whichButton(event)">
<div class="container" id="containerIdShow">
<div class="row">
<div class="col">
<p class="text-left">用户单位</p>
</div>
<div class="col">
<p class="text-left">端口</p>
</div>
<div class="col">
<p class="text-left">结束时间</p>
</div>
<div class="col">
<p class="text-left">状态</p>
</div>
<div class="col">
<p class="text-left">操作</p>
</div>
</div>
<div class="row">
<div class="col">
<input class="form-control" type="text" placeholder="" v-model="user" maxLength="64">
</div>
<div class="col">
<input class="form-control" type="number" placeholder="[8800-8900]" v-model="port" maxLength="4">
</div>
<div class="col">
<input class="form-control" type="date" placeholder="" v-model="stopDate" :min="dateXiaXian">
</div>
<div class="col">
</div>
<div class="col">
<button type="button" class="btn btn-outline-primary btn-sm" @click="addUser();console.log(123)" >添加</button>
</div>
</div>
<li class="list-group-item nav-item" >说明:web端php只能起一个进程,在linux环境下执行系统命令出于安全考虑不开放。请手动进入到目录启动</li>
<div class="row" v-for="(item,index) in userList">
<div class="col">
<p>
<span v-text='item.user'></span>
<a :href="'./index.html?ip='+item.ip+'&port='+item.port" target="_blank" class="btn btn-outline-warning btn-sm" >投屏</a>
<a :href="'./manage.html?ip='+item.ip+'&port='+item.port" target="_blank" class="btn btn-outline-warning btn-sm" >管理</a>
</p>
</div>
<div class="col">
<p><span v-text='item.port'></span></p>
</div>
<div class="col">
<p><span v-text='item.stopDate'></span></p>
</div>
<div class="col">
<p v-if="item.status">运行</p><p v-else>未运行</p>
</div>
<div class="col">
<button type="button" class="btn btn-outline-warning btn-sm" @click="exitUser(item.user, item.port)" >删除</button>
<button type="button" class="btn btn-outline-success btn-sm" :disabled="item.status" @click="startUser(item.user)" >启动</button>
<button type="button" class="btn btn-outline-secondary btn-sm" :disabled="!item.status" @click="stopUser(item.user, item.port)" >停止</button>
</div>
</div>
</div>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/echarts/dist/echarts.min.js"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/echarts-gl/dist/echarts-gl.min.js"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/echarts-stat/dist/ecStat.min.js"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/echarts/dist/extension/dataTool.min.js"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/echarts/map/js/china.js"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/echarts/map/js/world.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.0.0-alpha1/js/bootstrap.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/json2/20160511/json2.min.js"></script>
<script src="https://cdn.bootcss.com/vue/2.5.16/vue.min.js"></script>
<script type="text/javascript">
var ws = new WebSocket("ws://"+window.location.host+"/ws");
ws.onopen = function() {
ws.send("Hello, world");
};
ws.onmessage = function (evt) {
console.log(evt.data);
};
function whichButton(event)
{
if (event.button==2) {
ws.send("你点击了鼠标右键!")
} else {
ws.send("你点击了鼠标左键!")
}
}
Date.prototype.Format = function(fmt)
{
var o = {
"M+" : this.getMonth()+1,
"d+" : this.getDate(),
"h+" : this.getHours(),
"m+" : this.getMinutes(),
"s+" : this.getSeconds(),
"q+" : Math.floor((this.getMonth()+3)/3),
"S" : this.getMilliseconds()
};
if(/(y+)/.test(fmt))
fmt=fmt.replace(RegExp.$1, (this.getFullYear()+"").substr(4 - RegExp.$1.length));
for(var k in o)
if(new RegExp("("+ k +")").test(fmt))
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length==1) ? (o[k]) : (("00"+ o[k]).substr((""+ o[k]).length)));
return fmt;
}
const containerIdShow=new Vue({
el:"#containerIdShow",
data:{
user:"test",
port:"8888",
userList: [],
stopDate:"2022-01-01",
dateXiaXian:new Date().Format("yyyy-MM-dd"),
},
methods:{
startUser:function(user){
var _this=this;
var para={};
para.user = user;
para.action = "start";
jQuery.ajax({
url:"api/start",
async:true,
data:JSON.stringify(para),
dataType:"json",
type:"post",
success: function(result){
_this.userList=result.data;
}
});
},
stopUser:function(user, port){
var _this=this;
var para={};
para.user = user;
para.port = port;
para.action = "stop";
jQuery.ajax({
url:"api/stop",
async:true,
data:JSON.stringify(para),
dataType:"json",
type:"post",
success: function(result){
_this.userList=result.data;
}
});
},
exitUser:function(user, port){
var _this=this;
var para={};
para.user = user;
para.port = port;
para.action = "del";
jQuery.ajax({
url:"api/exit",
async:true,
data:JSON.stringify(para),
dataType:"json",
type:"post",
success: function(result){
_this.userList=result.data;
}
});
},
addUser:function(){
var _this=this;
var para={};
para.user = this.user;
para.port = this.port;
para.stopDate = this.stopDate;
para.action = "add";
console.log(para)
jQuery.ajax({
url:"api/addUser",
data:JSON.stringify(para),
dataType:"json",
type:"post",
success: function(result){
_this.userList=result.data;
alert(result.msg);
}
});
this.user="";
this.port=0;
}
},
mounted: function(){
var _this=this;
var para={};
para.action = "get";
jQuery.ajax({
url:"api/login",
data:JSON.stringify(para),
dataType:"json",
type:"post",
success: function(result){
console.log(result)
_this.userList=result.data;
}
});
},
created:function(){
}
});
</script>
</body>
</html>
|