微信小程序 WebSocket 通信 —— 在线聊天

news2024/11/26 9:43:13

         在Node栏目就讲到了Socket通信的内容,使用Node实现Socke通信,还使用两个流行的WebSocket 库,ws 和 socket.io,在小程序中的WebSocket接口和HTML5的WebSocket基本相同,可以实现浏览器与服务器之间的全双工通信。那么本篇就来讲关于微信小程序实现WebSocket通信完成在线聊天。

客户端流程

        这里的客户端也就是微信小程序了,同时还需要使用Node搭载一个服务器,WebSocket 是客服端与服务器之间专门建立的一条通道,先来了解一下过程:

        通过 wx.connectSocket 来创建 WebSocket 连接,来连接搭载好的Node服务器,连接之后发送数据可以通过 wx.sendSocketMessage ,可以发送数据到达客户端,同时也需要监听接收来自客户端发出的消息事件可以使用 wx.onSocketMessage ,知道这个流程之后,来看一下服务器的搭载流程。

服务器流程

        使用Node搭载服务器,WebSocket 服务是建立在HTTP之上的,可以通过引入 http 模块,使用 http.createServer() 创建 HTTP服务器,安装WebSocket库,当然这里可以使用Node中net模块,这里附上可供你参考的篇目:

         通过 WebSocket库来创建 WebSocket服务器,同时还需要设置 autoAcceptConnections ,对客服端发送的数据进行一个监控,以及关闭连接的监控,此外还可以进行其他的监控像错误,以及控制台的输入等操作。


图解

        用一个图来简单概述一下:

         下面来使用WebSokcet通信实现在线聊天,那先来看看需要完成的效果内容:


        以上就是接下来要完成的一个场景,先从小程序入手:

1. 聊天界面编写

        编写小程序的聊天界面,这里也不再多讲,主要还是讲一下注意点,聊天的数据不可能是一条两条,所以它应该是一个scroll-view滚动的,底部的输入框是固定在底部的,同时要避免底部会把最后的消息数据给遮挡了,聊天数据可以数组保存,然后通过wx:for渲染,是左边的还是右边发出的数据可以通过wx:if来进行判断显示左边还是右边,不破坏原型的DOM结构可以用block标签。

<!--pages/wxchat/wxchat.wxml-->

<!-- 聊天信息 -->
<view class="content">
  <scroll-view class="content-info" scroll-y scroll-top="{{scrollTop}}">
    <view class="content-list">
      <view class="content-li" wx:for="{{infoList}}" wx:key="id"> 
        <!-- 右边 -->
        <block wx:if="{{item.role === 'self'}}">
          <view class="right-info">
            <image class="myhead" src="{{head.self}}"></image>
            <text class="myinfo">{{item.content}}</text>
          </view>
        </block>
        <!-- 左边 -->
        <block wx:else>
          <view class="left-info">
            <image class="myhead" src="{{head.server}}"></image>
            <text class="myinfo">{{item.content}}</text>
            </view>
        </block>
      </view>
    </view>
  </scroll-view>
</view>

<!-- 操作区 -->
<view class="foot-input">
  <input type="text" class="send-input" placeholder="请输入聊天内容..." value="{{message}}" bindinput="handleChange"/>
  <view class="send-btn" bindtap="handleSend">发送</view>
</view>
/* pages/wxchat/wxchat.wxss */
page{
  height: 100%;
}
.content{
  height: 100%;
  display: flex;
}
.content-info .content-list{
  margin-bottom: 88rpx;
}
/* 信息 */
.content .content-info .content-list .content-li{
  clear: both;
  overflow: hidden;
}
.left-info{
  clear: both;
  margin: 20rpx 20rpx;
}
.left-info .myhead{
  float: left;
  width: 88rpx;
  height: 88rpx;
  /* background:#efefef; */
}
.left-info .myinfo{
  display: block;
  float: left;
  background: #75c475;
  max-width: 490rpx;
  margin-top: 10rpx;
  margin-left: 20rpx;
  padding: 10rpx 18rpx;
  border-radius: 20rpx;
}
.left-info::after{
  content:'';
  clear: both;
  display: block;
  height: 0;
  visibility: hidden;
}
.right-info{
  clear: both;
  margin: 10rpx 20rpx;
}
.right-info .myinfo{
    display: block;
    float: right;
    background: #efefef;
    max-width: 490rpx;
    margin-top: 10rpx;
    margin-right: 20rpx;
    padding: 10rpx 18rpx;
    border-radius: 20rpx;
}
.right-info .myhead{
    float: right;
    width: 88rpx;
    height: 88rpx;
    /* background-color: #efefef; */
}
.right-info::after{
  content:'';
  clear: both;
  display: block;
  height: 0;
  visibility: hidden;
}

/* 底部 */
.foot-input{
  position: fixed;
  bottom: 0;
  border-top: 1px solid #DDDDDD;
  width: 750rpx;
  height: 88rpx;
  line-height: 88rpx;
  background: #ffffff;
}
.foot-input .send-input{
  float: left;
  width: 560rpx;
  max-width: 600rpx;
  margin: 16rpx 0 0 20rpx;
  padding: 0 10rpx;
}
.foot-input .send-btn{
  float: right;
  margin: 11rpx 20rpx 0 0;
  width: 120rpx;
  height: 66rpx;
  line-height: 66rpx;
  text-align: center;
  background: #16AA51;
  color: #ffffff;
  border-radius: 10rpx;
}

2. 小程序创建服务器连接

        小程序要接入WebSocketServer服务器,首先要创建服务器连接,可以通过wx.connectSocket() 方法来创建连接,在小程序初始加载的时候就可以进行,同时还可以使用 wx.showToast() 方法提示接入成功与否;

/* pages/wxchat/wxchat.js*/
Page({
    onLoad:function(){
        this.createSocketServer();
    },

// 创建服务器连接
    createSocketServer(){
        // 服务器地址开头 ws/wss 
        url: 'ws://127.0.0.1:3000'
    }
    // 监控接入与否
    wx.onSocketOpen(()=>{
        // 接入成功
        wx.showToast({
            title: 'Socket接入成功',
            icon: 'success' 
        })
        // 接入问候语
    })
    
    // 监控信息 - 待写
    // wx.onSocketMessage(()=>{ ... })
    
    // 监控关闭
    wx.onSocketClose(()=>{
        // 服务器Socket连接关闭
        wx.showToast({
            title: 'Socket已关闭'
            icon: 'error'
        })
    })

    // 监控错误
    wx.onSocketError((err)=>{
        console.log('接入异常',err);
    })

})

3. 搭载Node服务器 - WebSocket服务器

        搭载Node服务器,WebSocket服务是建立在HTTP上,所以需要先引用http模块创建HTTP服务器再创建WebSocket服务器,在这里使用第三方的websocket库。

# 初始化 —— 在创建好的目标目录下进行初始化

npm init -y

 # 使用npm 安装 websocket 库

npm i websocket

# [可选] 使用 npm 安装 nodemon 

npm i nodemon

   * 不安装运行index.js文件使用每次修改后要执行     —— node index.js

   * 安装运行index.js文件使用每次修改不需要手动执行  

# 使用 npm 安装 moment.js —— 格式化时间

npm i moment -S

# 创建 index.js 文件进行编写代码

/* 服务器index.js文件 */ 

const http = require('http');
const WebSocketServer = require('websocket').server;
const moment = require('moment')

// 创建HTTP服务器
const httpServer = http.createServer((req,res)=>{
    res.writeHead(404);
    res.end();
})

// 创建websocket服务器
const wsServer = new WebSocketServer({
    httpServer,
    autoAcceptConnections : true    // 自动接受连接
})

// 监控接入
wsServer.on('connect',(connection)=>{
    // 监控数据信息message
    connection.on('message',(msg)=>{
        console.log('>> message' , msg);
        if( msg.type === 'utf8' ){
            var data = {
                content : '[自动回复] : 请等待用户接入回复...',
                date : moment(new Date()).format('YYYY-D-M , h:mm a')
            }
            connection.sendUTF( JSON.stringify(data) )
        }
    })

    // 监控关闭
    connection.on('close',()=>{
        console.log('Socket服务关闭');
    })
    
})

// 监听 3000 端口
httpServer.listen('3000',()=>{
    console.log('SERVER RUNNING ...')
})

4. 客户端发送数据信息 

        在input输入框中输入数据信息,通过在input框中绑定bindinput来监听获取输入框中的数据,将input框的value = {{ message }} ,便于做清空数据框操作。在点击"发送"按钮时将input中获取的信息通过sendSocketMessage 发送到服务器。

!--pages/wxchat/wxchat.js-->
Page({
    data:{
        head:{
         self:'https://profile.csdnimg.cn/8/D/A/2_weixin_52203618',
         server:'https://img2.baidu.com/it/u=4237756909,3713889849&fm=253&fmt=auto&app=138&f=JPEG?w=400&h=400'
    },
    },
    onLoad:function(){
        this.createSocketServer()
    },
    // 创建服务器连接
    createSocketServer(){
        ...
    },

    message:'',   // 待接收发送的消息

    // 获取Input框内的数据
    handleChange(opt){
        this.message = opt.detail.value
    }

    // 发送按钮触发事件
    handleSend(){
        // 发送的内容不为空
        if(this.message){
            // 发送
            wx.sendSocketMessage({
                data : this.message
            })
            // 收集我发出的信息 - 待写
        }else{
            wx.showToast({
                title: '请输入聊天内容',
                icon: 'none',
                duration: 1000
            })
        }
    }
})

5. 收集发送的数据信息

        通过wx.sendSocketMessage()将内容发送出去,需要将内容进行一个收集,收集到一个数组当中去,然后在页面通过wx:for的渲染方式显示出来,下面是对发送的数据信息进行收集:

<!--pages/wxchat/wxchat.js-->
Page({
    data:{
        head:{ ... },    // 用户头像
        infoList:[]      // 待收集数据信息
    },
    onLoad:function(){ ... },
    message: '',   // 待发送的数据信息
    id: 0,         // 数据信息标识
    // 发送按钮触发事件
    handleSend(){
        if(this.message){ 
            wx.sendSocketMessage({ data: this.message })
            // 收集我发出的信息
            var list = this.data.infoList
            list.push({
                id: this.id++ ,
                content: this.message ,
                role: 'self'    // 标识 —— 客户端发出 
            })
            // 更新
            this.setData({
                infoList : list
                message : ''    // 清空输入框
            })
            // 聊天视角 - 待写
        }else{
            wx.showToast({
                title: '请输入聊天内容',
                icon: 'none',
                duration: 1000
            })
        }
    } 
})

6. 接入服务器问候语

        接入服务器之后,客户端会自动发送 "你好" 的问候语;那么message是待发送的数据信息,监控客户端接入服务器的时候可以为message进行赋值,再调用handSend()方法发送,当然你可以调整一下handSend()方法,将其作为参数,这里就不做调整了,那么此时message绑定在input框的value值上,需要对message进行清空,否则当你再次点击发送的时候,没有输入任何数据也会发送 "你好" 的数据信息;

Page({
    data:{ ... },
    onLoad:function(){ this.createSocketServer() },
    // 创建服务器连接
    createSocketServer(){
        wx.connectSocket({ url: 'ws://127.0.0.1:3000/' })
        // 监控接入
        wx.onSocketOpen(() => {
          wx.showToast({
              title: 'Socket接入成功',
              icon: 'success'
          })    
          // 接入问候语
          this.message = '你好'
          this.handleSend()
          this.message = ''
        })
        ...
    }
})

7. 服务器发送数据信息到客户端

        客户端发送的数据信息在服务器中通过数据的监控可以知道,在前面已经编写了这段:

wsServer.on('connect',(connection)=>{
    // 监控是否有message信息
    connection.on('message',(msg)=>{
        console.log('>> message' , msg);
        if( msg.type === 'utf8'){        
            var data = {
                content: '[自动回复] : 请等待用户接入回复...',
                date: moment(new Date()).format('YYYY-D-M , h:mm a')
            }
            connection.sendUTF( JSON.stringify(data) )
        }
    })
})

         接下来是在服务器进行发送数据到客户端,那么服务器可以通过在控制台的输入发送到客户端,监控控制台的输入进行获取通过sendUTF发送到客户端。

/* 服务器index.js文件 */ 

...
wsServer.on('connect',(connection)=>{
    // 监控是否有message信息    
    connection.on('message',(msg)=>{ ... })    
    // 监控关闭
    connection.on('close',()=>{ ... })
    // 监控控制台输入
    process.stdin.on('data',(data)=>{
        var data = data.toString().trim()   // 清除前后空格
        data = {
            content : data,
            date : moment(new Date()).format('YYYY-D-M , h:mm a')
        }
        connection.sendUTF(JSON.stringify(data));    // 发送
    })
})
...

        服务器发送数据信息到客户端,那么需要在客户端进行监控数据信息

8. 客户端监控收集服务端发来的数据信息

         服务器发来的数据信息,在小程序客户端上需要对其进行一个数据信息的监控,同时还需要将这些数据信息使用数组收集起来,在页面使用wx:for渲染交互信息。

<!--pages/wxchat/wxchat.js-->
Page({
    data:{ ... },
    onLoad:function(){ ... },
    message: '',   // 待发送的数据信息
    id: 0,         // 数据信息标识
    createSocketServer(){
        // 创建服务器连接 
        wx.connectSocket({url: 'ws://127.0.0.1:3000/'})
        // 监控接入
        wx.onSocketOpen(()=>{ ... })
        // 监控信息
        wx.onSocketMessage((msg)=>{
            var result = JSON.parse(msg.data);
            result.id = this.id++ 
            result.role = 'Server'    // 标识 —— 服务端发出 
            // 收集
            var list = this.data.infoList
            list.push(result)
            // 更新
            this.setData({
                infoList : list
            })
            // 聊天视角 - 待写
        })
    }
})

9 .定位到消息处 —— 聊天视角

        能够在页面上正常的渲染客户端和服务器所发出的数据信息,接下来需要处理聊天视角的问题,聊天界面的聊天数据随着发送的增多会是聊天界面出现滑动状态 scroll-view ,那么当超出的聊天数据信息就需要定位到最底部发出消息的视角,不需要手动的向下滑动到发送数据信息的位置。通过 scroll-view 的标签中的scroll-top属性,同时要对每一个发送数据信息的内容高度进行计算,然后进行定位,那么可以对渲染的每一个 content-li 的高度进行计算。

<!--pages/wxchat/wxchat.js-->
Page({
    data: { ...
        scrolltop: 0  // 默认滑动定位
    },
    onLoad:function(){ ... }
    message: '',   // 待发送的数据信息
    id: 0,         // 数据信息标识
    createSocketServer(){
        // 创建连接
        wx.connectSocket({ ... })
        // 监控接入
        wx.onSocketOpen(()=>{ ... })
        // 监控信息
        wx.onSocketMessage((msg)=>{
            ...
            // 聊天视角
            this.rollingBottom()
        })
    },
    handleChange(opt){ ... },
    handleSend(){ 
        if(this.message){
            ...
            // 聊天视角
            this.rollingBottom()
        }else{
            ...
        }
    },
    // 聊天视角调整方法
    rollingBottom(){
        wx.createSelectorQuery().selectAll('.content-li').boundingClientRect(results=>{                
            results.forEach(result=>{
            console.log(result)
            this.setData({
                scrollTop : result.bottom
            })
        })
      }).exec()
    }
})

10 .状态设置优化 

        当客户端点击发送数据信息,服务器都会返回这个自动回复的内容,显然不友好,需要什么效果呢,就是当服务器不在线状态时,客户端发送什么,服务器仅回复【自动回复】来提示客户端当前不在线,如果服务器在控制台输出作出答复返回给客户端,此时服务器就是在线状态,那么当客户端再次发来的时候,服务器就不再继续返回【自动回复】

/* 服务器index.js文件 - 完整 */ 

const http = require('http');
const WebSocketServer = require('websocket').server;
const moment = require('moment')

// 在线状态
let onLineStatus = false    // 服务器默认不在线

// 创建Http服务器
const httpServer = http.createServer((req,res)=>{
    res.writeHead(404);
    res.end();
})

// 创建ws服务器
const wsSercer = new WebSocketServer({
    httpServer,
    autoAcceptConnections : true
})
wsSercer.on('connect',(connection)=>{
    // 监控是否有message信息
    connection.on('message',(msg)=>{
        console.log('>> message',msg)
        // if( msg.type === 'utf8'){
        if( msg.type === 'utf8' && !onLineStatus){
            var data = {
                content: '[自动回复] : 请等待用户接入回复...',
                date: moment(new Date()).format('YYYY-D-M , h:mm a')
            }
            connection.sendUTF( JSON.stringify(data) )
        }
    })

    // 监控关闭
    connection.on('close',()=>{
        console.log('close')
    })

    // 接收控制台输入
    process.stdin.on('data',(data)=>{
        var data = data.toString().trim()   // 清除前后空格
        data = {
            content : data,
            date : moment(new Date()).format('YYYY-D-M , h:mm a')
        }
        connection.sendUTF( JSON.stringify(data) )
        // 在线状态
        onLineStatus = true
    })
})

httpServer.listen('3000',()=>{
    console.log('SERVER RUNNING ...')
})

        以上就完成了整个使用WebSocket实现通信的代码,下面来进行测试一下吧效果吧!


测试效果

1. 启动服务器 node index.js / nodemon index.js

 2. 刷新一下微信小程序

3. 在控制台上输入发送数据信息 

 4. 客户端接收并回复

        以上就是这篇文章的全部内容了,这里可以借用局域网的url地址更换,可以实现一个简单的聊天室功能,那么本篇就到这,感谢大家的支持!!!

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/475554.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SSH 服务器、NFS 服务器、TFTP 服务器详解及测试

文章目录 前言一、SSH 服务器1、SSH 能做什么&#xff1f;2、安装 SSH 服务器3、测试 SSH 服务4、用 SecureCRT 测试 二、NFS 服务器1、NFS 能做什么&#xff1f;2、安装 NFS 软件包3、添加 NFS 共享目录4、启动 NFS 服务5、测试 NFS 服务器 三、TFTP 服务器1、TFTP 能做什么&a…

轻松掌握mysql事务的四大特性ACID及实现原理

1、介绍 要实现这四大特性&#xff0c;我们先了解下mysql中的缓冲池和数据页 2、保证原子性和一致性 1、通过undo log保证数据的原子性和一致性 undo log保证了事务的原子性和一致性。 3、保证隔离性 1、并发事务产生时容易产生的隔离性问题 脏读 不可重复读 幻读…

【数据库复习】第四章数据库保护 1

数据库安全性&#xff1a; 数据库的一大特点是数据可以共享 数据共享必然带来数据库的安全性问题 数据库系统中的数据共享不能是无条件的共享 用户标识与鉴别 用户名和口令易被窃取&#xff0c;每个用户预先约定好一个计算过程或者函数 存取控制 常用存取控制方法 自主存…

电子电气架构——车辆E/E架构常识

我是穿拖鞋的汉子,魔都中坚持长期主义的工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 人只有在举棋不定,无从把握的时候才感到疲惫。只有去行动就能获得解放,哪怕做的不好也比无所作为强! 本文主要介绍车辆E/E架构常识,主要涉及E/E架构面临…

LNMP、Tomca

构建Nginx服务器 使用源码包安装nginx软件包 [rootproxy ~]# yum -y install gcc pcre-devel openssl-devel #安装依赖包 [rootproxy ~]# useradd -s /sbin/nologin nginx [rootproxy ~]# tar -xf nginx-1.17.6.tar.gz [rootproxy ~]# cd nginx-1.17.6 [rootproxy …

【Shell编程之循环语句与函数】

目录 一、for循环语句示例:示例1示例2 示例3 二、跳出循环举例 转义符三、while 语句的结构示例: 四、until语句的结构1、基本格式 五、seq命令 一、for循环语句 读取不同的变量值&#xff0c;用来逐个执行同一组命令 #!/bin/bash for(( i0;i<5;i ))i0 定义for循环i变量初…

【逻辑位移和算数位移】

<< 运算符 && >> 运算符 正数位移 当 x>>n 中 x 为正数时&#xff0c;会将x的所有位右移x位&#xff0c;同时左边高位补0 显而易见&#xff0c;运算结束后&#xff0c;值为1 。 可知右移n位&#xff0c;结果就是 x / 2^n&#xff1a;7 / 2 ^2 1;…

运行vue项目报DONE Build complete. The dist directory is ready to be deployed.解决办法

一、问题描述 今天在运行一个vue项目时发现运行途中报这样一个错误&#xff0c;经过查阅相关资料可知&#xff0c;这是dist文件夹下 二、解决办法 根据官方文档&#xff0c;目录需要启动一个 HTTP 服务器来访问 (除非你已经将 publicPath 配置为了一个相对的值)&#xff0c;所…

flex垂直方向布局与overflow结合使用

主要是需要留意 flex布局和overflow 之间的关系&#xff0c; 最外面的container 和 里面的main-box 之间分别使用了flex布局 和 overflow:hiddenmain-box 和 里面的main-body 之间分别使用了 flex布局 和 overflow:auto 有点类似于聊天的窗口布局 <!DOCTYPE html> <h…

zabbix监控远程主机

zabbix监控远程主机 在Zabbix服务器上安装Zabbix代理程序 在远程主机上安装Zabbix代理程序。安装方式取决于操作系统&#xff0c;可以从Zabbix官网上下载相应的安装包进行安装。 监控agent1 在agent1上安装agent yum install zabbix-agent另外在zabbix server上要关闭防火…

【前端知识】内存泄漏与垃圾回收机制 (上)

【前端知识相关分享】内存泄漏与垃圾回收机制 &#xff08;上&#xff09; 1. 内存的生命周期1.1 内存生命周期的一般流程1.2 C&#xff0c;JS和python内存分配和释放的区别 2. JS中的内存管理2.1 两种数据类型与两种内存一个思考2.2 两种内存空间的区别对比 3. 内存泄漏的定义…

HMM理论学习笔记-隐马尔可夫模型的三个元素、假设和问题

文章目录 概率论基础条件概率全概公式边缘概率联合概率联合概率与边缘概率的关系贝叶斯公式&#xff08;条件联合概率&#xff09;马尔科夫链的概念 HMM简述HMM的三个元素符号定义1、状态转移概率矩阵A2、观测概率矩阵B3、初始状态概率向量π HMM的三个假设1、齐次马尔可夫假设…

netstat命令解析

一、linux系统中netstat命令的帮助信息 └──╼ $netstat -h usage: netstat [-vWeenNcCF] [<Af>] -r netstat {-V|--version|-h|--help}netstat [-vWnNcaeol] [<Socket> ...]netstat { [-vWeenNac] -i | [-cnNe] -M | -s [-6tuw] }-r, --route …

VMware12安装图解

目录 一、介绍VMware虚拟机 二、安装VMware12虚拟机 三、VMware虚拟机内部新建虚拟机 清理磁盘 一、介绍VMware虚拟机 VMware是一个虚拟机。 什么是虚拟机&#xff1f;字面意思‘虚拟’&#xff0c;那就不算是真的&#xff1b;‘机’可以理解为一台电脑或者一个电脑系统。…

SimpleDateFormat以及Date的使用

Date Date currentTime new Date(); 获取当前的时间 输出&#xff1a; System.out.println(currentTime); 就会以这样的格式输出 那我们不想要这样的格式&#xff0c;而是输出格式怎么办呢&#xff1f; SimpleDateFormat闪亮登场 食用方法&#xff1a; SimpleDateForma…

前端埋点采集到的数据怎么发送到服务端?

水善利万物而不争&#xff0c;处众人之所恶&#xff0c;故几于道&#x1f4a6; 目录 1. Image请求 2. Ajax请求 3. WebSocket 连接 1. Image请求 1. 通过 Image请求将采集的数据发送到服务器。这种方式比较适合少量数据的采集&#xff0c;因为 lmage请求不需要返回任何数据…

【Python】中文乱码问题与解决方案 深入分析

一直以来&#xff0c;python中的中文编码就是一个极为头大的问题&#xff0c;经常抛出编码转换的异常&#xff0c;python中的str和unicode到底是一个什么东西呢&#xff1f; 在本文中&#xff0c;以哈来解释作示例解释所有的问题&#xff0c;“哈”的各种编码如下&#xff1a; …

数据库单实例升级

一、单实例环境,全时长二个半钟多。详细图文说明到这下载 1、停止所有oracle相关进程。 Emctlstop dbconsole Isqlplusctl stop Lsnrctl stop sqlplus /nolog sql>conn /as sysdba Connectedtoanidleinstance. sql>shutdown 然后&#xff0c;冷备份下数据库cp…