当前位置:   article > 正文

鸿蒙arkts做一个简易聊天功能,包含存储聊天记录,通知,和发送接收消息

鸿蒙arkts做一个简易聊天功能,包含存储聊天记录,通知,和发送接收消息

首先是服务器端的实现,利用ws库

第一步,下载ws模块

npm i ws

第二步,粘贴代码

var express = require('express');
var router = express.Router();
var {addressBookModel} = require("../model/model/lzx")
导入ws模块
const WebSocket = require("ws");
let clients=[]; //存所有连接上的用户
// 创建WebSocket服务器
const wss = new WebSocket.Server({ port: 8080 });
​
// 监听连接建立事件
wss.on("connection", function(socket) {
  console.log("WebSocket连接已建立");
​
  // 监听接收到客户端发送的消息
  socket.on("message", function(message) {
    console.log("接收到户端发送的消息:" + message);
    //每个客户端都存上自己发来的phone做为唯一的id
    //连接上后就压进数组
        clients.push({id:message,ws:socket})
​
  });
​
  // 监听连接关闭事件
  socket.on("close", function() {
    console.log("WebSocket连接已关闭");
  });
});
​
// 当有人发送消息的时候
router.post('/sendMsg', (req, res) =>{
  //前端传过来的数据,otherId是当前要接受消息的人的id,message是消息主体,_id是当前发送消息的人的id,otherName是当前发送消息人的项目
    let {otherId,message,_id,otherName} = req.body
    console.log(otherId);
    const datalist = {
      _id,
      message,
      otherName,
    }
    const Medatalist = {
      _id,
      message,
    }
    console.log(datalist);
    //循环遍历     找到你要发送的人  他的id  就发送
    clients.forEach((ele) =>{
      console.log('eleid',ele.id);
      console.log(otherId);
      if(otherId==ele.id){
        ele.ws.send(JSON.stringify(datalist));
      } 
    });
    //发送给自己客户端的数据
    res.send(Medatalist)
  })
​
​
//获取我们的通讯录
router.get('/getAddressBooks',async function (req, res, next) {
  let {_id} = req.query
  let data = await addressBookModel.find({uid:_id})
  res.send({
    code:200,
    data
  });
});
​
module.exports = router;

然后是客户端的实现

第一步,配置网络权限

module.json5
{
        "name": "ohos.permission.INTERNET",
      },

注意!!!!文章中的this.id.slice(1,this.id.length-1)是给我们从首选项获取的数据进行了一次切割,因为我们首选存储后再读取出来可能会有多一个引号的问题,就例如""aaa"",也就是说全部都成了两个引号,所以需要切割

//引入鸿蒙官方的websocket模块
import webSocket from '@ohos.net.webSocket';
//映入鸿蒙官方的通知模块,就是一发消息,我们的手机上通知的那个模块
import NotificationManager from '@ohos.notificationManager';
//引入axios
import axios from '../../http/index'
//引入路由
import router from '@ohos.router';
//引入首选项存储,这里我是利用首选项存储了我们当前用户的id,用户名,头像等
import SharePre from '../../util/SharePre'
//引入鸿蒙官方提供的文件管理,用来存储聊天记录
import common from '@ohos.app.ability.common';
//文件操作模块
import fs from '@ohos.file.fs';
@Entry
@Component
struct Chat{
    //读取上级传来的params,这里我的params中是要聊天的那个人的信息
    @State params:any = router.getParams()
    @State msg:string = ""
    @State username:string = ""
    @State _id:string = ""
    @State imgPath:string = ""
    //存储聊天记录
    @State chatRecords:Array<{_id:string,message:string}> = []
    
    //获取上下文,用于存储聊天记录
    private context = getContext(this) as common.UIAbilityContext
    //声明一个ws,用于websocket的使用
    private ws
    async aboutToAppear(){
        //获取首选项存储的id,用户名和头像
        this._id = await SharePre.getPreferenceValue('MyPreferences','_id','666') as string
        this.username = await SharePre.getPreferenceValue('MyPreferences','username','666') as string
        this.imgPath = await SharePre.getPreferenceValue('MyPreferences','imgPath','666') as string
​
        //读取聊天记录,从我们存储的聊天记录文件中获取聊天记录
        let file = fs.openSync(this.context.filesDir+`/${this.params._id}.txt`,fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE)
        let buf = new ArrayBuffer(2048)
        let leng = fs.readSync(file.fd,buf,{offset:0})
        this.chatRecords = JSON.parse(String.fromCharCode.apply(null,new Uint8Array(buf.slice(0,leng))))
        fs.closeSync(file)
        
        //创建websocket连接
        this.ws = webSocket.createWebSocket()
        this.ws.connect("ws://59.110.165.22:8080")
        this.ws.on("open",(err,value)=>{
            if(!err){
                console.log("连接成功")
                //在这里直接先像服务器发送一次请求,先发送一次请求是为了将id添加到后端的用户列表中
                this.ws.send(this._id.slice(1,this._id.length-1))
            }
​
        })
​
        this.ws.on("message",(err,value)=>{
            if(!err){
                console.log("收到消息"+value)
                this.chatRecords.push(JSON.parse(value))
                //这里打印的是我们聊天记录的存储位置
                console.log("我是涛的文件",this.context.filesDir)
                //存储聊天记录
                let file = fs.openSync(this.context.filesDir+`/${this.params._id}.txt`,fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE)
                fs.write(file.fd,JSON.stringify(this.chatRecords))
                fs.close(file)
                
                //收到消息时通知
                let notificationRequest = {
                    id: 1,
                    content: {
                        contentType: NotificationManager.ContentType.NOTIFICATION_CONTENT_BASIC_TEXT, // 普通文本类型通知
                        normal: {
                            title: JSON.parse(value).otherName,
                            text: JSON.parse(value).message,
                        }
                    }
                }
                NotificationManager.publish(notificationRequest, (err) => {
                    if (err) {
                        console.error(`[ANS] failed to publish, error[${err}]`);
                        return;
                    }
                    console.info(`[ANS] publish success`);
                });
            }
​
        })
​
        this.ws.on("close",(err,value)=>{
            if(!err){
                console.log("连接断开")
            }
        })
​
    }
​
    async sendData(){
        console.log('params_id',this.params._id)
        try {
            //给后端发送请求,发送数据
            const response = await axios.post("lzx/sendMsg",{otherId:this.params._id,message:this.msg,_id:this._id.slice(1,this._id.length-1),otherName:this.username.slice(1,this.username.length-1)});
            console.log(JSON.stringify(response));
            this.chatRecords.push({"_id":this._id.slice(1,this._id.length-1),message:response.data.message})
            //这里打印的是我们聊天记录的存储位置
            console.log("我是涛的文件",this.context.filesDir)
            //存储聊天记录
            let file = fs.openSync(this.context.filesDir+`/${this.params._id}.txt`,fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE)
            fs.write(file.fd,JSON.stringify(this.chatRecords))
            fs.close(file)
            //发送后清空聊天数据
            this.msg = ""
        } catch (error) {
            console.error(JSON.stringify(error));
        }
    }
​
​
    @Builder popupBuilder() {
        Row({ space: 2 }) {
            Image($r("app.media.icon")).width(24).height(24).margin({ left: 5 })
            Text('This is Custom Popup').fontSize(15)
        }.width(200).height(50).padding(5)
    }
​
    @Builder Title(){
        Row(){
            Text(this.params.username)
            NavRouter(){
                Text("...")
                    //这里我们做了一个跳转的操作,跳转到我们对方的详细信息页面,对于聊天没有帮助,可以不看
                    .onClick(()=>{
                        router.pushUrl(
                            {
                                url:"pages/MyMessage/ChatSettings",
                                params:this.params
                            }
                        )
                    })
            }
        }.width("90%").justifyContent(FlexAlign.SpaceAround)
​
​
    }
​
    build(){
        Navigation() {
​
        Column(){
            Column(){
​
                List({space:10}){
​
                    ForEach(this.chatRecords,(item)=>{
                        ListItem(){
                            if(item._id==this._id.slice(1,this._id.length-1)){
                                Row(){
                                    Row(){
                                        Text(item.message)
                                    }
                                    .width(150)
                                    .height(50)
                                    .backgroundColor("#FFB6C1")
                                    .borderRadius(15)
                                    Text(":")
                                    //使用时需要进行切片,因为默认会多加一层引号,如果不切片,出不来效果
                                    Image(this.imgPath.slice(1,this.imgPath.length-1))
                                        .width(50)
                                        .height(50)
                                        .borderRadius(50)
                                }
                                .width("100%")
                                .justifyContent(FlexAlign.End)
                            }else if(item._id==this.params._id){
                                Row(){
                                    Image(this.params.imgPath)
                                        .width(50)
                                        .height(50)
                                        .borderRadius(50)
                                        .onClick(()=>{
                                            router.pushUrl(
                                                {
                                                    url:"pages/MyMessage/ChatSettings",
                                                    params:this.params
                                                }
                                            )
                                        })
                                    Text(":")
                                    Row(){
                                        Text(item.message)
                                    }
                                    .width(150)
                                    .height(50)
                                    .backgroundColor("#FFF")
                                    .borderRadius(15)
                                }
                                .width("100%")
​
                            }
​
                        }
                    })
                }.width("100%").height("100%").backgroundColor("#eee")
            }
                .width("100%")
                .height("93%")
            Row(){
                TextInput({placeholder:"请输入您想要发送的内容",text:this.msg})
                    .width("80%")
                    .height(50)
                    .onChange((e)=>{
                        this.msg = e
                    })
                Button("发送")
                    .height(50)
                    .width(70)
                    //发送消息
                    .onClick(()=>{
                        this.sendData()
                    })
            }
            .width("100%")
​
        }
        .width('100%')
        .height('100%')
        .justifyContent(FlexAlign.SpaceBetween)
        }
        .title(this.Title())
        .titleMode(NavigationTitleMode.Mini)
    }
}
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/325479
推荐阅读
相关标签
  

闽ICP备14008679号