当前位置: 首页 > news >正文

阿里云服务器官网登录入口/深圳seo推广公司

阿里云服务器官网登录入口,深圳seo推广公司,客户网站建设完成后需要什么,建设银行的官方网站公告先把封装好的地址安上(非本人封装):webrtc-webphone: 基于JsSIP开发的webrtc软电话 jssip中文文档:jssip中文开发文档(完整版) - 简书 jssip使用文档:(我没有运行过,但…

先把封装好的地址安上(非本人封装):webrtc-webphone: 基于JsSIP开发的webrtc软电话

jssip中文文档:jssip中文开发文档(完整版) - 简书

jssip使用文档:(我没有运行过,但是他写的很清楚,反正比我好)jssip+webrtc+freeswitch实现电话网页及遇到的488状态码问题_freeswitch 488_weixin_39715323的博客-CSDN博客

正常使用由于web限制应该在https上使用,但是http也不是不可以,我放到下一篇文章了,这就说怎么使用

我这用的是webrtc+jssip

webrtc-webphone已经实现了我的需求,所以我没有使用原生jssip

特主要实现的功能有:注册,拨叫,接听,保持,恢复

我的项目中需要静音(指我不能说话,通话人可以讲话)

所以我将hold(保持)和unhold(恢复)改成了mute和unmute

 下面是完整代码和方法说明:

1.init(注册citbar)config中需要使用ip地址、端口号、extNo拨号人、extPwd密码

2.handleAgentBarBtnClick(通话状态更改)

        makecall(拨号)

        hangup(挂断)

        hold(静音)

        unhold(取消静音)

3.onbeforeunload (通话中刷新对讲群组中没有退出,导致群组中有多个同一个人)

4.beforeDestroy(切换页面后没有退出群组,刷新不走这个方法)

注意:

1.不要重复拨号,状态卡住后就能同一个设备对话了bug

2.如果想切换页面还能通话就不要beforeDestroy,但是在其他页面在回来时会导致状态不一致,而且容易出现卡状态,所以我将通话操作放在index最顶层里面

<template><div class="top"><div style="padding: 0 30px;"><div style="display: flex;padding-top: 3px;"><!-- 设备树插件 --><organizationTree ref="organizationTree"></organizationTree><div style="width:77vw;height:80vh; margin-top: 5px;"><div class="photo_date" style="position:relative"><div style="display:flex;min-width:30%"><div class="text_type photo_deviceName " v-show="groupName" style="text-align: center;">{{groupName}}</div><div class="text_type" :class="meetingStatus==2?' meetingName1':' meetingName'"style="width: 125px;text-align: center;">{{meetingStatus==2?meetingName:meetingName1}}</div></div><div style="position: absolute;right: 0;" v-show="createBy==userName"><div v-show="meetingStatus==2" class="btn_type photo_meeting_btn" @click="meetingAll"style="position:absolute; right:135px;width: 140px;height: 35px;line-height: 35px;">邀请全部成员</div><div class="bg_btn_type photo_meeting_btn" @click="meeting"style="position:absolute; right:0;width: 125px;height: 35px;line-height: 35px;">{{meetingStatus==1?'开始会议':'结束会议'}}</div></div></div><div class=""><div class="deviceList_title"><div class="deviceList_title_text" style="width:15%">名称</div><div class="deviceList_title_text" style="width:15%">imei</div><div class="deviceList_title_text" style="width:15%">类型</div><div class="deviceList_title_text" style="width:15%">状态</div><div class="deviceList_title_text" style="width:15%">会议状态</div><div class="deviceList_title_text" style="width:24%">操作</div><!-- <div class="deviceList_title_text">操作</div> --></div><div v-show="deviceList" class="deviceList"><div class="deviceList_list" :class="item.id==itemId?'deviceList_list1':''"v-for="(item,index) in deviceList" :key="item.id" @mouseover="mouseover(item.id)"@mouseleave="mouseout()"><!-- <el-tooltip :content="item.name" placement="bottom" effect="light"> --><div class="deviceList_title_text" style="width:15%">{{item.devName}}</div><!-- </el-tooltip> --><div class="deviceList_title_text" style="width:15%">{{item.imei}}</div><div class="deviceList_title_text" style="width:15%">{{item.devTypeName}}</div><div class="deviceList_title_text" style="width:15%">{{dictionary(item.devStatus,'dev_status',item.imei)}}</div><div class="deviceList_title_text" style="width:15%">{{dictionary(item.memberStatus,'meeting_member_status')}}</div><div style="width:24%;"><div v-if="meetingStatus==2"><div v-if="item.imei == createBy&&item.imei == userName"><div v-if="item.devStatus==3||item.devStatus==4||item.devStatus==5||item.devStatus==1"><div style="width:100%;justify-content: center;" class="deviceList_operate"><div class="deviceList_title_text1" @click="speak('request')"v-if="item.memberStatus!=3&&item.memberStatus!=1&&item.memberStatus!=4&&item.memberStatus!=5"><div>开始发言</div></div><div class="deviceList_title_text1" @click="speak('request')" v-if="item.memberStatus==3"><div>结束发言</div></div><div class="deviceList_title_text1" @click="outMeeting" v-if="item.memberStatus==2">离开会议</div><div class="deviceList_title_text1" @click="inMeeting" v-if="item.memberStatus==1">进入会议</div></div></div></div><div v-if="item.imei != createBy"><div v-if="item.devStatus==3||item.devStatus==4||item.devStatus==5||item.devStatus==1"><div style="width:100%;justify-content: center;" class="deviceList_operate"v-show="createBy==userName&&isInOrOutMeeting&&deviceList[0].memberStatus==2"><div class="deviceList_title_text1" @click="speak('call',item.imei,'start')"v-if="item.memberStatus!=3&&item.memberStatus!=1&&item.memberStatus!=4&&item.memberStatus!=5"><div>点名发言</div></div><div class="deviceList_title_text1" @click="speak('call',item.imei,'end')"v-if="item.memberStatus==3"><div>结束发言</div></div><div class="deviceList_title_text1" @click="inOrOut('out',item.imei)"v-if="item.memberStatus==2">请离会议</div><div class="deviceList_title_text1" @click="inOrOut('in',item.imei)"v-if="item.memberStatus==1">拉入会议</div></div></div></div></div></div></div></div></div></div></div></div></div></template>
<script>import Header from "../home/header/index";import Footer from "../home/footer/index";import webSocketClass from "@/utils/webSocket";import { postWarnStatus } from "@/api/AlarmRecord";import organizationTree from "./deviceTree/organizationTree"import { devicetree } from "@/api/system/deviceTree";import { timestampToTime } from "../../../utils/time.js"import { addGroup, delGroup, getGroup, listGroup, updateGroup, updateMeetingStatus, selectDeviceGroupDetailList, deviceRequestTalking, inOrOutMeeting } from "@/api/system/group";import { listData } from "@/api/system/dict/data";import Ctibar from './AgentBar/ctibar.js';var audio = document.getElementById('audio');var constraints = {audio: true,video: true,mandatory: {maxWidth: 640,maxHeight: 360}};URL = window.URL || window.webkitURL;var eventHandlers = {'progress': function (e) {console.log('call is in progress');},'failed': function (e) {console.log('call failed: ', e);},'ended': function (e) {console.log('call ended : ', e);},'confirmed': function (e) {console.log('call confirmed');}};export default {dicts: ["warn_type"],components: {Header,Footer,organizationTree},data() {return {// 以下群组isGroup: false,createBy: '',isInOrOutMeeting: false,isSpeak: false,itemId: '',meetingStatus: '',groupDetail: {},isMike: false,deviceList: null,meetingName1: "会议未开始",meetingName: "会议中",groupName: "",dataList: null,userId: JSON.parse(sessionStorage.getItem("userInfo")).userId,userName: JSON.parse(sessionStorage.getItem("userInfo")).userName,// 查询参数queryParams: {pageNum: 1,pageSize: 10,deptId: null,planName: null,status: null,},total: 0,deviceTreeList: [],title: "",num: 1,groupId: '',dictionaryList: [],websocket: null,//初始化SDK所需要的配置config: {host: '39.152.2.103',port: '5066',proto: false,extNo: '',extPwd: '20181231',autoRegister: true,debug: true,//stunServer: 'stun.1.google.com',   可自行修改使用stun服务器地址stateEventListener: this.stateEventListener},//坐席分机号agentNo: '',//客户号码customerNo: '',//拨号弹窗showDial: false,//转接弹窗showTransferDial: false,//转接号码transNum: '',numList: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '*', '0', '#',],agentStatus: 'DISCONNECTED',statusMap: {CONNECTED: '已连接',DISCONNECTED: '网络断开',REGISTERED: '已注册',UNREGISTERED: '未注册',REGISTER_FAILED: '注册失败',IN_CALL: '通话中',INCOMING_CALL: '来电振铃',OUTGOING_CALL: '外呼振铃',HOLD: '保持中',CALL_END: '通话结束'},timer: null,timerString: '00:00:00',outNum: '',isHold: true};},computed: {classObject() {const bool1 = this.alarmArr.length > 1;const bool2 = this.alarmArr.length === 1;return {tanchuangbox: true,"tanchuangbox-height-multi": bool1,"tanchuangbox-height-single": bool2,};},},mounted() {this.init()},methods: {// 以下群组inMeeting() {this.loadingFun()var body = {devImei: this.userName,flag: 'in',groupId: this.groupId,}inOrOutMeeting(body).then(response => {if (response.data.success) {} else {this.$modal.msgError(response.data.message);}this.loading.close();},error => {this.loading.close();});},outMeeting() {this.loadingFun()var body = {devImei: this.userName,flag: 'out',groupId: this.groupId,}inOrOutMeeting(body).then(response => {if (response.data.message == '已离开!') {} else {this.$modal.msgError(response.data.message);}this.loading.close();},error => {this.loading.close();});},inOrOut(flag, devImei) {this.loadingFun()var body = {devImei: devImei,flag: flag,groupId: this.groupId,}inOrOutMeeting(body).then(response => {console.log("123123123", response)if (response.data.success) {this.$modal.msgSuccess(response.data.message);} else {this.$modal.msgError(response.data.message);}this.loading.close();},error => {this.loading.close();});},loadingFun() {this.loading = this.$loading({lock: true,text: 'Loading',spinner: 'el-icon-loading',background: 'rgba(0, 0, 0, 0.7)'});},speak(type, devImei, flag) {this.loadingFun()var flagg = ''if (type == 'request') {flagg = !this.isSpeak ? 'start' : 'end'devImei = this.userName} else {flagg = flag}var body = {devImei: devImei,flag: flagg,groupId: this.groupId,type: type,}deviceRequestTalking(body).then(response => {if (response.data.success) {if (type == 'request') {}this.$modal.msgSuccess(response.data.message);//恢复发言} else {this.$modal.msgError(response.data.message);this.hold()}this.loading.close();},error => {this.loading.close();});},// 1、进入元素mouseover(index) {this.itemId = index},// 4、离开元素mouseout() {this.itemId = ''},ws() {console.log('{"groupId":' + this.groupId + '}')this.websocket.webSocketSendMsg('{"groupId":' + this.groupId + '}')},devStatus(devStatus) {for (const i in this.deviceList) {if (this.deviceList[i].devStatus == devStatus) {this.deviceList[i].devStatus = devStatus}}},dictionary(e, type, imei) {for (const i in this.dictionaryList) {if (this.createBy == imei && e == 4) {return '在线'}if (this.dictionaryList[i].dictValue == e && this.dictionaryList[i].dictType == type) {return this.dictionaryList[i].dictLabel}}},handleAdd() {// this.reset();// this.open = true;this.title = "添加群组";},tableRowClassName({ row, rowIndex }) {return 'photo';},rowClass({ row, rowIndex }) {return 'text-align: center;background-color: #1A1D30;color: #fff'},meetingAll() {var meetingStatusAll = 2var params = {groupId: this.groupId,meetingStatus: meetingStatusAll}updateMeetingStatus(params).then(response => {if (response.code == 200) {this.$modal.msgSuccess(response.msg);} else {this.$modal.msgError(response.msg);}});},meeting() {this.loadingFun()if (this.deviceList != null) {console.log('meetingStatusmeetingStatus', this.meetingStatus)var params = {groupId: this.groupId,meetingStatus: this.meetingStatus == 1 ? 2 : 1}updateMeetingStatus(params).then(response => {setTimeout(() => {if (response.code == 200) {if (this.meetingStatus == 1) {if (sessionStorage.getItem('groupId') == this.groupId) {this.handleAgentBarBtnClick('hangup')sessionStorage.setItem('groupId', '')}this.isInOrOutMeeting = falsethis.isHold = truethis.loading.close()}}}, 5000);});}},//孙组件向父组件传递数据wsMeetingStatus(isInterface) {console.log('isMeeting状态:', isInterface)this.meetingStatus = isInterface},groupDeviceItemClick(item) {// this.handleAgentBarBtnClick('hangup')this.isSpeak = falsethis.deviceList = []this.groupId = item.idthis.meetingStatus = item.meetingStatusthis.groupName = item.groupNamethis.createBy = item.createBythis.item = itemvar params = { groupInfoId: item.id, pageNum: 0, pageSize: 0, }selectDeviceGroupDetailList(params).then(response => {this.deviceList = response.rowsthis.total = this.deviceList.lengththis.ws()if (this.deviceList[0].memberStatus == 3 &&this.deviceList[0].imei == this.userName) {this.isSpeak = true;}if (this.deviceList[0].memberStatus == 2 &&this.deviceList[0].imei == this.userName) {if (sessionStorage.getItem("groupId") == this.groupId) {this.isInOrOutMeeting = truereturn}if (sessionStorage.getItem("groupId")) {} else {this.call()}}});},onClickDialOutside(event) {console.log(event)this.showDial = false},onClickTransDialOutside(event) {this.showTransferDial = false;},handleAgentBarBtnClick(name) {console.log(name + '当前')if (name === 'login') {this.login();} else if (name === 'logout') {this.logout();} else if (name === 'answer') {this.answer();} else if (name === 'hangup') {this.hangup();} else if (name === 'makecall') {this.makeCall('9*' + this.groupId)} else if (name === 'hold') {this.hold();} else if (name === 'unhold') {this.unhold();} else if (name === 'transfer') {this.transfer(this.transNum)}},login() {this.init()Ctibar.register()},logout() {Ctibar.unregister()},makeCall(phone) {if (phone === "" || phone === undefined) {console.error('无效的号码,请重新输入!');return}Ctibar.makecall(phone);},hold() {Ctibar.hold();},unhold() {Ctibar.unhold();},answer() {Ctibar.answer();},hangup() {Ctibar.hangup();},transfer(phone) {console.info("触发转接", phone)Ctibar.transfer(phone);},//外呼拨号盘handleDialBtnClick(val) {this.outNum += val;this.$refs.outNumInput.focus();},//转接拨号盘handleTransDialBtnClick(val) {this.transNum += val;this.$refs.transNumInput.focus();},//参数为时间差秒数,返回这两个时间差并格式化computeTimeDiff(diff) {diff = Math.round(diff / 1000);let hour = Math.floor(diff / 3600).toString().padStart(2, '0');let min = Math.floor((diff - hour * 3600) / 60).toString().padStart(2, '0');let sec = (diff % 60).toString().padStart(2, '0');return hour + ':' + min + ':' + sec;},//重置时间restoreTime(origin) {clearInterval(this.timer);this.timerString = '00:00:00';this.timer = setInterval(() => {this.timerString = this.computeTimeDiff(new Date().getTime() - origin);}, 1000);},//状态变更回调stateEventListener(event, data) {//debug使用console.log('当前event为: ' + event + ', 当前data为: ' + JSON.stringify(data))this.agentStatus = eventlet origin = new Date().getTime();switch (event) {case "CONNECTED":this.agentNo = data.localAgentthis.restoreTime(origin);break;case "DISCONNECTED":this.restoreTime(origin);break;case "UNREGISTERED":this.restoreTime(origin);break;case "OUTGOING_CALL":this.customerNo = data.otherLegNumber;this.restoreTime(origin);break;case "INCOMING_CALL":this.customerNo = data.otherLegNumber;//播放来电振铃音this.playRingMedia();this.restoreTime(origin);break;case "IN_CALL":this.stopPlayRingMedia();this.restoreTime(origin);// this.timer = setInterval(() => {// }, 1000);console.log('当前是否hold', this.isHold)if (this.isHold) {setTimeout(() => {this.handleAgentBarBtnClick('hold')this.isHold = false// 方法区}, 500);}break;case "CALL_END":this.stopPlayRingMedia();//挂机铃声this.playHangupMedia()this.restoreTime(origin);break;default:}},//播放挂机铃声playHangupMedia() {const _this = this;var hangupAudio = document.getElementById("hangupMediaAudioId")if (!hangupAudio) {hangupAudio = document.createElement('audio');hangupAudio.id = 'hangupMediaAudioId';hangupAudio.hidden = true;hangupAudio.src = 'wav/hangup.wav'document.body.appendChild(hangupAudio);}hangupAudio.play();},//播放来电振铃playRingMedia() {const _this = this;_this.stopPlayRingMedia();var ringAudio = document.getElementById("ringMediaAudioId")if (!ringAudio) {ringAudio = document.createElement('audio');ringAudio.id = 'ringMediaAudioId';ringAudio.hidden = true;ringAudio.src = 'wav/ring.wav';ringAudio.loop = 'loop';document.body.appendChild(ringAudio);}ringAudio.play();},//停止播放来电振铃stopPlayRingMedia() {const _this = this;var ringAudio = document.getElementById("ringMediaAudioId");if (ringAudio) {document.body.removeChild(ringAudio);}},//初始化方法init() {this.config.extNo = this.userNameif (sessionStorage.getItem("freeSwitchWs") != null) {this.config.host = sessionStorage.getItem("freeSwitchWs").split(":")[0]this.config.port = sessionStorage.getItem("freeSwitchWs").split(":")[1]}Ctibar.initSDK(this.config)let url = `/ws/` + this.userId + '/group/device/push';this.websocket = new webSocketClass(url)this.websocket.getWebSocketMsg(evt => {// 客户端接收服务端返回的数据var data = JSON.parse(evt.data);console.log("websocket返回的数据123:", data);switch (data.flag) {case "group"://会议状态this.$refs.organizationTree.setGroupList(data, this.groupId)console.log("websocket返回的数据123:", data);breakcase "memberStatus"://成员状态for (const i in this.deviceList) {console.log('123123132', data.member);if (this.deviceList[i].imei == data.member) {this.deviceList[i].devStatus = data.memberStatus;}}breakcase "memberMeetingStatus"://成员会议状态for (const i in this.deviceList) {if (this.deviceList[i].imei == data.member) {this.deviceList[i].memberStatus = data.memberMeetingStatus;}}if (this.groupId == data.groupId && this.userName == data.member && this.createBy == data.member) {if (data.memberMeetingStatus == 3) {this.isSpeak = true;this.unhold()console.log('数据this.isInOrOutMeeting1111', this.isSpeak)} else {this.isSpeak = false;this.hold()}}if (data.memberMeetingStatus == 4) {this.loading.close()}if (!this.isInOrOutMeeting && this.groupId == data.groupId && this.userName == data.member && this.createBy == data.member && data.memberMeetingStatus == 2) {this.hold()if (sessionStorage.getItem("groupId") &&sessionStorage.getItem("groupId") !== this.groupId) {} else {console.log('this.isInOrOutMeeting1111', data.memberMeetingStatus)this.call()}}if (this.createBy == data.member && data.memberMeetingStatus == 1 && this.userName == data.member) {this.handleAgentBarBtnClick('hangup')sessionStorage.setItem("groupId", '')this.isInOrOutMeeting = falsethis.isSpeak = falsethis.isHold = true}break}})},setGroup(group) {this.isGroup = group},call() {this.handleAgentBarBtnClick('makecall')sessionStorage.setItem("groupId", this.groupId)this.isInOrOutMeeting = trueif (this.deviceList[0].imei != this.createBy) {// this.groupDeviceItemClick(this.item)}var that = thiswindow.onbeforeunload = (e) => {console.log('this.isInOrOutMeeting', that.isInOrOutMeeting)if (that.isInOrOutMeeting) {that.handleAgentBarBtnClick('hangup')sessionStorage.setItem("groupId", '')that.websocket.closeSocket()window.onbeforeunload = null}}this.loading.close()this.isInOrOutMeeting = truethis.isHold = true}},beforeDestroy() {  //进行监听销毁console.log('1231232131232132131,', this.isInOrOutMeeting)if (this.isInOrOutMeeting) {this.handleAgentBarBtnClick('hangup')sessionStorage.setItem("groupId", '')this.websocket.closeSocket()window.onbeforeunload = null}},};
</script>

相关文章:

web 语音通话 jssip

先把封装好的地址安上&#xff08;非本人封装&#xff09;&#xff1a;webrtc-webphone: 基于JsSIP开发的webrtc软电话 jssip中文文档&#xff1a;jssip中文开发文档&#xff08;完整版&#xff09; - 简书 jssip使用文档&#xff1a;&#xff08;我没有运行过&#xff0c;但…...

随风摇曳的她——美蕨(matlab实现)

目录 1 随风摇曳的她 2 摇曳带来的哲思 3 Matlab代码实现 1 随风摇曳的她 梦幻的场景、浪漫的气息&#xff0c;带上心爱的人&#xff0c;拥抱在这片花海之下&#xff0c;便有了电影男女主角的氛围感&#xff1b; 就算阅尽了世间风貌&#xff0c;也抵不上和她在一起时锦短情长&a…...

时序数据库的流计算支持

一、时序数据及其特点 时序数据&#xff08;Time Series Data&#xff09;是基于相对稳定频率持续产生的一系列指标监测数据&#xff0c;比如一年内的道琼斯指数、一天内不同时间点的测量气温等。时序数据有以下几个特点&#xff1a; 历史数据的不变性数据的有效性数据的时效…...

springboot启动流程 (3) 自动装配

在SpringBoot中&#xff0c;EnableAutoConfiguration注解用于开启自动装配功能。 本文将详细分析该注解的工作流程。 EnableAutoConfiguration注解 启用SpringBoot自动装配功能&#xff0c;尝试猜测和配置可能需要的组件Bean。 自动装配类通常是根据类路径和定义的Bean来应…...

ansible-roles模块

roles用于层次性&#xff0c;结构化地组织playbook&#xff0c;roles能够根据层次型结构自动装载变量文件&#xff0c;tasks以及handlers等。要使用只要载playbook中使用include指令引入即可。 &#xff08;roles就是通过分别将变量&#xff0c;文件&#xff0c;任务&#xff…...

聊聊我做 NeRF-3D重建性能优化经历

我们新推出大淘宝技术年度特刊《长期主义&#xff0c;往往从一些小事开始——工程师成长总结专题》&#xff0c;专题收录多位工程师真诚的心路历程与经验思考&#xff0c;覆盖终端、服务端、数据算法、技术质量等7大技术领域&#xff0c;欢迎一起沟通交流。 本文为此系列第四篇…...

未磁科技全球首台64通道无液氦心磁图仪及首个培训基地落户北京安贞医院

【全球首台64通道无液氦心磁图仪在北京安贞医院举行开机仪式】 近日&#xff0c;在北京安贞医院举行了未磁科技全球首台64通道无液氦心磁图仪开机仪式&#xff0c;中国医学装备协会赵自林理事长、北京安贞医院纪智礼书记、张宏家院长、宋现涛教授&#xff0c;以及未磁科技蔡宾…...

SpringBoot 如何使用 ApplicationEventPublisher 发布事件

SpringBoot 如何使用 ApplicationEventPublisher 发布事件 在 SpringBoot 应用程序中&#xff0c;我们可以使用 ApplicationEventPublisher 接口来发布事件。事件可以是任何对象&#xff0c;当该对象被发布时&#xff0c;所有监听该事件的监听器都会收到通知。 下面是一个简单…...

【深度学习】2-3 神经网络-输出层设计

前馈神经网络(Feedforward Neural Network)&#xff0c;之前介绍的单层感知机、多层感知机等都属于前馈神经网络&#xff0c;它之所以称为前馈(Feedforward)&#xff0c;或许与其信息往前流有关&#xff1a;数据从输入开始&#xff0c;流过中间计算过程&#xff0c;最后达到输出…...

Python网络爬虫开发:使用PyQt5和WebKit构建可定制的爬虫

部分数据来源:ChatGPT 引言 在网络爬虫开发中,使用Web浏览器模拟用户行为是非常重要的。而在这个过程中,基于 WebKit 的框架可以提供比其他技术更紧密的浏览器集成,以及更高效、更多样化的页面交互方式。 在本文中,我们将通过一个使用基于 WebKit 的爬虫示例,并与类似…...

Laya3.0游戏框架搭建流程(随时更新)

近两年AI绘图技术有了长足发展&#xff0c;准备把以前玩过的游戏类型重制下&#xff0c;也算是圆了一个情怀梦。 鉴于unity商用水印和启动时间的原因&#xff0c;我决定使用Laya来开发。目前laya已经更新到了3.0以上版本&#xff0c;就用目前比较新的版本。 之后关于开发中遇到…...

.net 软件开发模式——三层架构

三层架构是一种常用的软件开发架构模式&#xff0c;它将应用程序分为三个层次&#xff1a;表示层、业务逻辑层和数据访问层。每一层都有明确的职责和功能&#xff0c;分别负责用户交互、业务处理和数据存储等任务。这种架构模式的优点包括易于维护和扩展、更好的组织结构和代码…...

SpringBoot如何优雅的实现重试功能

文章目录 使用背景spring-retry介绍快速使用加入依赖开启Retry使用参数 使用背景 在有些特定场景&#xff0c;如和第三方对接。 我们调用接口时需要支持重试功能&#xff0c;第一次调用没成功&#xff0c;我们需要等待x秒后再次调用。 通常会设置重试次数&#xff0c;避免业务…...

【CEEMDAN-VMD-GRU】完备集合经验模态分解-变分模态分解-门控循环单元预测研究(Python代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…...

OpenText Exceed TurboX(ETX)—— 适用于 UNIX、Linux 和 Windows 的远程桌面解决方案

由于新技术的采用&#xff0c;以及商业全球化和全球协作的现实&#xff0c;几乎所有企业&#xff08;无论其规模和所处行业&#xff09;的员工的工作方式、时间和地点都发生了重大变化。业务领导者正在推动其 IT 部门提出解决方案&#xff0c;以帮助其远程员工提高工作效率&…...

【人工智能】— 逻辑回归分类、对数几率、决策边界、似然估计、梯度下降

【人工智能】— 逻辑回归分类、对数几率、决策边界、似然估计、梯度下降 逻辑回归分类Logistic Regression ClassificationLogistic Regression: Log OddsLogistic Regression: Decision BoundaryLikelihood under the Logistic ModelTraining the Logistic ModelGradient Desc…...

k8s pod “cpu和内存“ 资源限制

转载用于收藏学习&#xff1a;原文 文章目录 Pod资源限制requests&#xff1a;limits&#xff1a;docker run命令和 CPU 限制相关的所有选项如下&#xff1a; Pod资源限制 为了保证充分利用集群资源&#xff0c;且确保重要容器在运行周期内能够分配到足够的资源稳定运行&#x…...

datagrip 连接 phoenix

jar替换完后尽量重启datagrip. 然后重新连接即可. 不重启貌似报错... 效果:...

黑客入侵的常法

1.无论什么站&#xff0c;无论什么语言&#xff0c;我要渗透&#xff0c;第一件事就是扫目录&#xff0c;最好一下扫出个上传点&#xff0c;直接上传 shell &#xff0c;诸位不要笑&#xff0c;有时候你花很久搞一个站&#xff0c;最后发现有个现成的上传点&#xff0c;而且很容…...

VB报警管理系统设计(源代码+系统)

可定时显示报警系统是一个能够定时并及时报警,提醒人们安全有效地按计划完成任务的系统。本论文从软件工程的角度,对可定时显示报警系统做了全面的需求分析,简要说明了该系统的构思、特点及开发环境;阐述了系统的主要功能,论述了它的设计与实现,并且叙述了系统的测试与评…...

Redis入门 - Redis Stream

原文首更地址&#xff0c;阅读效果更佳&#xff01; Redis入门 - Redis Stream | CoderMast编程桅杆Redis入门 - Redis Stream Redis Stream 是 Redis 5.0 版本新增加的数据结构。 Redis Stream 主要用于消息队列&#xff08;MQ&#xff0c;Message Queue&#xff09;&#xf…...

微服务中常见问题

Spring Cloud 组件 Spring Cloud五大组件有哪些&#xff1f; Eureka&#xff1a;注册中心 Ribbon&#xff1a;负载均衡 Feign&#xff1a;远程调用 Hystrix&#xff1a;服务熔断 Zuul/Gateway&#xff1a;服务网关 随着SpringCloud Alibaba在国内兴起&#xff0c;我们项目中…...

更新删除清理购物车

目录 1 更新购物车 2 取会员门店购物车项 3 取会员门店购物车项(无缓存) 4 删除门店购物车某项 5 删除门店购物车多项 6 清理门店购物车 7 清理门店购物车 8 添加商品至购物车 9 添加商品至购物车...

基于Intel NUC平台的字符设备陀螺仪GX5-25驱动程序

陀螺仪GX5-25连接到Intel NUC上可能需要进行一些设备树的修改和编写驱动程序的工作。这是因为陀螺仪GX5-25可能需要特定的设备树配置和驱动程序来与Intel NUC的硬件和操作系统进行通信。 如果陀螺仪GX5-25没有官方的Linux驱动程序或文档&#xff0c;您可能需要自己编写驱动程序…...

建立小型医学数据库(总结)

建立小型医学数据库 小型医学数据库可以用于存储和管理医学数据&#xff0c;如患者病历、药品信息、试验结果等。这对于医疗机构和科研机构来说非常必要&#xff0c;可以提高数据管理和共享的效率&#xff0c;进而促进医学研究和诊疗水平的提升。 建立小型医学数据库有以下基本…...

Git学习笔记

文章目录 一. 引入1. SCM软件2. 概念 二. GitHubDesktop三. Git1. 版本号 (底层原理)1.1 视频笔记1.2 实操记录 2. Git命令2.0 汇总2.1 仓库操作2.2 文件操作2.3 分支操作2.4 标签操作2.5 远程仓库 四. idea操作 一. 引入 1. SCM软件 2. 概念 集中式版本控制 文件冲突 可以上…...

vue面试题1. 请说下封装 vue 组件的过程?2. Vue组件如何进行传值的?3. Vue 组件 data 为什么必须是函数?4. 讲一下组件的命名规范

1. 请说下封装 vue 组件的过程&#xff1f; 首先&#xff0c;组件可以提升整个项目的开发效率。能够把页面抽象成多个相对独立的模块&#xff0c;解决了我们传统项目开发&#xff1a;效率低、难维护、复用性等问题。 分析需求&#xff1a;确定业务需求&#xff0c;把页面中可以…...

Docker使用记录

文章目录 Docker基本使用Docker配置查看状态卸载安装使用 apt 存储库安装在 Ubuntu 上安装 Docker 桌面(非必要) Docker实例使用现有的镜像查找镜像拖取镜像列出镜像列表更新镜像导出镜像删除镜像导入镜像清理镜像查看容器导出容器导入容器-以镜像的方式创建容器重启容器进入容…...

OpenCV(图像处理)-基于Python-形态学处理-开运算、闭运算、顶帽、黑帽运算

1. 形态学2. 常用接口2.1 cvtColor()2.2 图像二值化threshod()自适应阈值二值化adaptiveThreshod() 2.3 腐蚀与膨胀erode()getStructuringElement()dilate() 2.4开、闭、梯度、顶帽、黑帽运算morphologyEx() 1. 形态学 OpenCV形态学是一种基于OpenCV库的数字图像处理技术&…...

chatgpt赋能python:Python支持跨平台软件开发

Python支持跨平台软件开发 作为一种高级编程语言&#xff0c;Python 以其丰富的库和跨平台支持而备受开发人员欢迎。Python 通过将应用程序的可移植性最大化&#xff0c;使得开发人员可以轻松地在不同的操作系统平台上构建和部署软件。 跨平台支持 Python 支持各种不同的操作…...