diff --git a/package-lock.json b/package-lock.json index 9e4c256..1e8e120 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3177,6 +3177,15 @@ "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", "dev": true }, + "bufferutil": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.8.tgz", + "integrity": "sha512-4T53u4PdgsXqKaIctwF8ifXlRTTmEPJ8iEPWFdGZvcf7sbwYo6FKFEX9eNNAnzFZ7EzJAQ3CJeOtCRA4rDp7Pw==", + "optional": true, + "requires": { + "node-gyp-build": "^4.3.0" + } + }, "builtin-status-codes": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", @@ -4478,6 +4487,15 @@ "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=", "dev": true }, + "d": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.2.tgz", + "integrity": "sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw==", + "requires": { + "es5-ext": "^0.10.64", + "type": "^2.7.2" + } + }, "dashdash": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", @@ -5167,6 +5185,36 @@ "is-symbol": "^1.0.2" } }, + "es5-ext": { + "version": "0.10.64", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.64.tgz", + "integrity": "sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==", + "requires": { + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.3", + "esniff": "^2.0.1", + "next-tick": "^1.1.0" + } + }, + "es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", + "requires": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, + "es6-symbol": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.4.tgz", + "integrity": "sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg==", + "requires": { + "d": "^1.0.2", + "ext": "^1.7.0" + } + }, "escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -5193,6 +5241,17 @@ "estraverse": "^4.1.1" } }, + "esniff": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/esniff/-/esniff-2.0.1.tgz", + "integrity": "sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==", + "requires": { + "d": "^1.0.1", + "es5-ext": "^0.10.62", + "event-emitter": "^0.3.5", + "type": "^2.7.2" + } + }, "esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", @@ -5234,6 +5293,15 @@ "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", "dev": true }, + "event-emitter": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", + "integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==", + "requires": { + "d": "1", + "es5-ext": "~0.10.14" + } + }, "event-pubsub": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/event-pubsub/-/event-pubsub-4.3.0.tgz", @@ -5397,6 +5465,14 @@ } } }, + "ext": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", + "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==", + "requires": { + "type": "^2.7.2" + } + }, "extend": { "version": "3.0.2", "resolved": "https://registry.npm.taobao.org/extend/download/extend-3.0.2.tgz", @@ -7044,8 +7120,7 @@ "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "dev": true + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" }, "is-utf8": { "version": "0.2.1", @@ -7872,6 +7947,11 @@ "integrity": "sha1-rCetpmFn+ohJpq3dg39rGJrSCBw=", "dev": true }, + "next-tick": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", + "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==" + }, "nice-try": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", @@ -7921,6 +8001,12 @@ } } }, + "node-gyp-build": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.0.tgz", + "integrity": "sha512-u6fs2AEUljNho3EYTJNBfImO5QTo/J/1Etd+NVdCj7qWKUSN/bSLkZwhDv7I+w/MSC6qJ4cknepkAYykDdK8og==", + "optional": true + }, "node-ipc": { "version": "9.2.1", "resolved": "https://registry.npmjs.org/node-ipc/-/node-ipc-9.2.1.tgz", @@ -11117,6 +11203,14 @@ "readable-stream": "^2.0.1" } }, + "stompjs": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/stompjs/-/stompjs-2.3.3.tgz", + "integrity": "sha512-5l/Ogz0DTFW7TrpHF0LAETGqM/so8UxNJvYZjJKqcX31EVprSQgnGkO80tZctPC/lFBDUrSFiTG3xd0R27XAIA==", + "requires": { + "websocket": "^1.0.34" + } + }, "stream-browserify": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", @@ -11645,6 +11739,11 @@ "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", "dev": true }, + "type": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", + "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==" + }, "type-fest": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", @@ -11667,6 +11766,15 @@ "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", "dev": true }, + "typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "optional": true, + "requires": { + "is-typedarray": "^1.0.0" + } + }, "uglify-js": { "version": "3.4.10", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.10.tgz", @@ -11956,6 +12064,15 @@ "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", "dev": true }, + "utf-8-validate": { + "version": "5.0.10", + "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.10.tgz", + "integrity": "sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==", + "optional": true, + "requires": { + "node-gyp-build": "^4.3.0" + } + }, "util": { "version": "0.11.1", "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", @@ -12798,6 +12915,37 @@ } } }, + "websocket": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/websocket/-/websocket-1.0.34.tgz", + "integrity": "sha512-PRDso2sGwF6kM75QykIesBijKSVceR6jL2G8NGYyq2XrItNC2P5/qL5XeR056GhA+Ly7JMFvJb9I312mJfmqnQ==", + "optional": true, + "requires": { + "bufferutil": "^4.0.1", + "debug": "^2.2.0", + "es5-ext": "^0.10.50", + "typedarray-to-buffer": "^3.1.5", + "utf-8-validate": "^5.0.2", + "yaeti": "^0.0.6" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "optional": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "optional": true + } + } + }, "websocket-driver": { "version": "0.7.4", "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", @@ -12971,6 +13119,12 @@ "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", "dev": true }, + "yaeti": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/yaeti/-/yaeti-0.0.6.tgz", + "integrity": "sha512-MvQa//+KcZCUkBTIC9blM+CU9J2GzuTytsOUwf2lidtvkx/6gnEp1QvJv34t9vdjhFmha/mUiNDbN0D0mJWdug==", + "optional": true + }, "yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", diff --git a/package.json b/package.json index 85c0526..d5871f4 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ "postcss-pxtorem": "^5.1.1", "px2rem-loader": "^0.1.9", "quill": "^1.3.7", + "stompjs": "^2.3.3", "tinymce": "^6.8.3", "vue": "^2.6.14", "vue-codemirror": "^4.0.6", diff --git a/src/api/index.js b/src/api/index.js index 03b35bd..c92574f 100644 --- a/src/api/index.js +++ b/src/api/index.js @@ -44,4 +44,6 @@ export default { getStartTime: `python/python/getStartTime`, getProductSystemTheme: `nakadai/mall/getProductSystemTheme`, heartbeatDetection : `nakadai/message/heartbeatDetection`, + createQueue : `python/rabbitMessage/createQueue`, + endRunningProcess : `python/python/endRunningProcess`, } \ No newline at end of file diff --git a/src/components/TestPanel.vue b/src/components/TestPanel.vue index d70e0ef..65af807 100644 --- a/src/components/TestPanel.vue +++ b/src/components/TestPanel.vue @@ -319,6 +319,12 @@ import "codemirror/theme/monokai.css"; import "codemirror/theme/base16-light.css"; import { mavonEditor } from 'mavon-editor' import 'mavon-editor/dist/css/index.css' +import Stomp from 'stompjs' +export const IP = "x.108.x.33" // 自己的mq服务ip +export const MQTT_USERNAME = 'huoran' // 连接用户名, todo: read from database +export const MQTT_PASSWORD = 'huoran2024' // 连接密码, todo: read from database +export const VIRTUAL_HOST = '15674' // 侦听器端口 + export default { data () { return { @@ -396,7 +402,10 @@ export default { reportVisible: false, tableHeight: 0, dragIds: ['panelHeader', 'aside', 'main', 'infoContainer'], - submiting: false + submiting: false, + client: '', + accountId: '', + runCodeType: '', }; }, components: { @@ -419,6 +428,10 @@ export default { await this.getEntryTime() + newmain.$on('changeRunStatus', val => { + this.runCodeType = val + }) + if (this.assessmentId) { // 考核(考核才会从外面带进来assessmentId,练习是默认显示第一个项目,竞赛会带进来competitionId) this.getAssList() } else { // 练习 @@ -840,6 +853,14 @@ export default { } } }, + vscodeRunCode (data) { + // this.$parent.workbench[i].codeId = data.codeId + // this.$parent.workbench[i].retResult = 1 + }, + emptyRunCode (data) { + this.$parent.workbench[0].codeId = data.codeId + this.submit() + }, // 提交询问 confirmSubmit () { if (this.submiting) return false @@ -869,17 +890,17 @@ export default { const promises = [] taskList.map(async (e, i) => { (e.code || e.codeResult) && promises.push(new Promise(async (resolve, reject) => { - const { code, codeId } = await this.$post(this.api.runPythonCode, { + this.runCodeType = 'vscodeRunCode' + await this.$post(this.api.runPythonCode, { code: e.code, bcId: e.judgmentId, cid: this.courseId, projectId: this.projectId, userAnswer: e.codeResult || null, - type: 0 + type: 0, + sort: i }) - this.$parent.workbench[i].codeId = codeId this.$parent.workbench[i].answer = e.codeResult - this.$parent.workbench[i].retResult = 1 resolve() })) }) @@ -889,16 +910,14 @@ export default { } else { // 如果全部都没运行直接点提交,则主动运行一个空代码。(不然会造成上次运行的结果,这次进来不运行直接提交的话,会无法取到运行结果) if (!pointList.find(e => e.codeId)) { + this.runCodeType = 'emptyRunCode' this.$post(this.api.runPythonCode, { code: '', bcId: pointList[0].judgmentId, cid: this.courseId, projectId: this.projectId, type: 0 - }).then(({ codeId }) => { - this.$parent.workbench[0].codeId = codeId - this.submit() - }).catch(err => { + }).then(res => { }).catch(err => { this.submiting = false }) } else { @@ -1198,6 +1217,52 @@ export default { // 监听socket消息 this.socket.onmessage = this.getMessage; }, + + // 消息队列获取 + connect () { + let ws = new WebSocket(`ws://124.71.74.9:15674/ws`); + this.client = Stomp.over(ws); + //初始化连接 + const headers = { + login: MQTT_USERNAME, + passcode: MQTT_PASSWORD + }; + //进行连接 + this.client.connect(headers.login, headers.passcode, this.onConnected, this.onFailed, 'pyhost'); + }, + onConnected: function () { + //订阅频道 + const topic = '/amq/queue/pythonQueue_' + this.accountId; + this.client.subscribe(topic, this.responseCallback, this.onFailed); + }, + onFailed: function (frame) { + console.log("MQ Failed: " + frame); + // this.$message.error('连接失败') + }, + // 回传消息 + responseCallback: function (frame) { + const data = JSON.parse(frame.body) + + console.log("接收信息:", data, typeof data); + if (typeof data === 'object') { + newmain.$emit('setPid', '') + if (this.runCodeType) { + this[this.runCodeType](data) + } else { + newmain.$emit('runCode', data) + } + this.runCodeType = '' + } else if (typeof data === 'string') { + newmain.$emit('setPid', data) + } + }, + // 断开相应的连接 + close: function () { + this.client.disconnect(function () { + console.log("已退出账号"); + }) + }, + // 心跳检测 heartbeatDetection () { setInterval(async () => { @@ -1206,7 +1271,10 @@ export default { }, // 获取用户详情 getUserDetail () { - this.$get(this.api.queryUserInfoDetails).then(res => { + this.$get(this.api.queryUserInfoDetails).then(async (res) => { + this.accountId = res.result.userAccount.id + await this.$get(this.api.createQueue) + this.connect(); this.initSocket(res.result.userAccount) }).catch(res => { }) }, diff --git a/src/components/codemirror.vue b/src/components/codemirror.vue index c52dba1..a72ccf0 100644 --- a/src/components/codemirror.vue +++ b/src/components/codemirror.vue @@ -9,20 +9,31 @@