首页 > 其他分享 >基于EasyTcp4Net开发一个功能较为完善的去持久化聊天软件

基于EasyTcp4Net开发一个功能较为完善的去持久化聊天软件

时间:2024-07-29 16:06:28浏览次数:16  
标签:set 持久 get 发送 EasyTcp4Net Length 聊天 public 消息

之前自己写了一篇介绍TCP的一些常用的功能介绍和特征,并且用代码做了示例,最终开发了一个EasyTcp4Net的TCP工具库,其最大的特色就是使用了微软提供的高性能库中的一些数据结构来处理TCP数据。
最近辞职待业在家,也没啥事做,就利用自己写的TCP通讯库基础上开发了一个示例的聊天程序,功能包括,文本发送,图片发送,断线重连,消息发送成功确认,消息发送失败提示等。

示例

发消息给自己

image

收到消息

image

发送图片

image

消息发送中

image

重连中

image

发送失败

image

数据包结构以及拆包

定义数据包结构

数据包结构定义了每次发送一个数据的完整的数据结构,我们将包体长度定义在包头中来解决粘包和断包的问题。
数据包我们采用了简单的序列化成byte数组的方式来发送。

[StructLayout(LayoutKind.Sequential)]
public class Message<TBody> : IMsssage<TBody> where TBody : Packet
{
    //数据包包体长度 4字节
    public int BodyLength { get; private set; }
    //消息类型 4字节
    public MessageType MessageType { get; set; }
    public TBody? Body { get; set; }
    private Message<TBody> Deserialize(byte[] bodyData)
    {
        var bodyStr = System.Text.Encoding.Default.GetString(bodyData);
        Body = JsonSerializer.Deserialize<TBody>(bodyStr);

        return this;
    }

    public static Message<TBody> FromBytes(ReadOnlyMemory<byte> data)
    {
        Message<TBody> packet = new Message<TBody>();
        packet.BodyLength = BinaryPrimitives.ReadInt32BigEndian(data.Slice(0, 4).Span);
        packet.MessageType = (MessageType)BinaryPrimitives.ReadInt32BigEndian(data.Slice(4, 4).Span);
        packet.Deserialize(data.Slice(8, packet.BodyLength).Span.ToArray());

        return packet;
    }

    public byte[] Serialize()
    {
        var Length = 4 + 4;
        var bodyArray = System.Text.Encoding.Default.GetBytes(JsonSerializer.Serialize(Body));
        BodyLength = bodyArray.Length;
        Length += bodyArray.Length;
        byte[] result = new byte[Length];
        result.AddInt32(0, bodyArray.Length);
        result.AddInt32(4, (int)MessageType);
        Buffer.BlockCopy(bodyArray, 0, result, 8, bodyArray.Length);

        return result;
    }

    public TBody GetBody()
    {
        return Body;
    }
}

public interface IMsssage <out TBody> where TBody : Packet
{
    public TBody GetBody();
}

我们在服务端和客户端根据我们定义的数据结构,来调用EasyTcp4Net提供的固定包头来解析数据包

_easyTcpClient.SetReceiveFilter(new FixedHeaderPackageFilter(8, 0, 4, false));

文本/图片发送

我们可以定义消息基类,再拓展两个消息类,一个文本消息,一个图片消息

public class SendMessagePacket : Packet
{
    public string MessageId { get; set; } = Guid.NewGuid().ToString();
    public string From { get; set; }
    public string To { get; set; }
}

图片消息

public class SendImageMessagePacket : SendMessagePacket
{
    public byte[] Data { get; set; }
    public string FileName { get; set; }
}

文本消息

public class SendTextMessagePacket : SendMessagePacket
{
    public string Text { get; set; }
}

我们还需要在界面中增加相关的文本和图片的ViewModel
发送消息的时候,发送者可以立刻将消息添加到聊天界面,然后等待收到自己发送的消息从服务端发来的时候,根据状态判断消息是否发送成功,等待的时候可以将消息设置发送中的界面状态显示,这种发送消息逻辑和微信基本一致。

断线处理

利用EasyTcp4Net提供的断线的事件,可以非常方便的在服务端知道客户端突然断开了,或者在客户端知道和服务端连接断开了。

客户端

_easyTcpClient.OnDisConnected += async (obj, e) =>
{
    Title = Title + _disConnectTip;
    await ReConnectAsync();
};

主要是触发了重连的机制。

服务端

 _easyTcpServer.OnClientConnectionChanged += (obj, e) =>
 {
     if (e.Status == ConnectsionStatus.DisConnected)
     {
         _accounts.TryRemove(e.ClientSession.SessionId, out var account);
     }
 };

主要是将该用户从在线列表中移除。

总结

总体来说做一个聊天软件需要考虑的细节比较多。
示例地址:https://github.com/BruceQiu1996/EasyChat

标签:set,持久,get,发送,EasyTcp4Net,Length,聊天,public,消息
From: https://www.cnblogs.com/qwqwQAQ/p/18330325

相关文章

  • Telegram 可以通过聊天功能分享吗?
    大家好,请精通telegramAPI的人。我正在尝试启动这种pfehare弹出窗口,它看起来像是我的快速API中的telegram原生的,但没有运气。你知道它应该如何工作吗?我一直在尝试一切,但我什至无法在电报文档中找到任何内容谢谢很遗憾,TelegramAPI没有提......
  • pinia持久化存储(pinia-plugin-persistedstate)
    快速开始|pinia-plugin-persistedstate(prazdevs.github.io)安装pnpmpnpmaddpinia-plugin-persistedstatenpmnpmipinia-plugin-persistedstateyarnyarnaddpinia-plugin-persistedstate将插件添加到pinia实例上import{createPinia}from'pinia'import......
  • 仿微信im源码开源部署/社交聊天即时通讯im源码[PHP+uniapp]/直播+PC+安卓+IOS
    在数字化时代,即时通讯(InstantMessaging,IM)已成为人们日常生活中不可或缺的一部分,无论是工作协作、社交互动还是日常交流,IM应用都扮演着至关重要的角色。从早期的ICQ、MSN到如今的微信、WhatsApp、Telegram等,IM技术不断演进,为用户提供了更加丰富、便捷、安全的沟通体验。本文旨在......
  • 使用 WebSocket 实现实时聊天
    个人名片......
  • 手把手搭建im即时通讯app源码(基于PHP即时通讯源码聊天系统协议)uniapp全开源框架
    即时通讯(InstantMessaging,IM)系统是现代互联网应用中不可或缺的一部分,它允许用户进行实时的文本、语音、视频交流。随着技术的发展,IM系统的功能越来越丰富,如红包、客服、禁言等。本文将深入探讨如何使用PHP语言结合WebSocket、UniApp等技术开发一个功能完备的即时通讯系......
  • 【docker】配置mysql及数据持久化
    【docker】配置mysql及数据持久化前言一、使用docker时常用的命令1、用usermod命令向docker用户组添加新用户2、给docker的images打标签二、docker相关的环境配置1、配置文件的生效条件/etc/profile文件的环境变量所有用户可用,只在用户登陆的时候执行一次,安装编译好的全......
  • 可持久化数据结构
    可持久化数据结构简介分类部分可持久化所有版本都可以访问,但是只有最新版本可以修改。完全可持久化所有版本都既可以访问又可以修改。实际应用几何计算(扫描线),字串处理(合并操作rope),版本回溯,函数式编程。可持久化线段树引入[P3834【模板】可持久化线段树2]首先考虑静态......
  • 最新保护生态max聊天全自动挂机项目
    项目概述本文档旨在介绍一款视频挂机聊天应用程序的运作机制及其盈利模式。该应用程序专为男性用户设计,通过充值与女性用户进行文字和视频聊天。本文将详细阐述项目的盈利模式、优势、辅助软件功能及设备要求。一、项目背景在当前的数字娱乐市场中,视频挂机聊天应用为用户提......
  • 最新nacos下载安装,版本号2.4.0,nacos持久化存储到本地mysql中,nacos配置登录账户密码
    官网:https://nacos.io/zh-cn/docs/quickstart/quick-start1.下载地址:https://github.com/alibaba/nacos/releases网络不好,很难下载。直接使用git克隆,然后自己编译,这是最快的了。克隆:gitclonehttps://github.com/alibaba/nacos.git然后到根目录中(我的:E:\Demos\nacos),执行cmd命令:mv......
  • 使用Spring Boot和Netty打造高性能聊天服务(一):基础入门
    使用SpringBoot和Netty打造高性能聊天服务(一):基础入门在现代互联网应用中,实时聊天功能已经成为了许多应用的标配。无论是社交应用、在线客服系统,还是游戏中的实时交流,聊天功能都扮演着重要角色。今天,我们将使用SpringBoot和Netty来构建一个高性能的聊天服务。本文是系列文章的第......