LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

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


2024年8月4日 18:51 本文热度 966

示例

发消息给自己

收到消息

发送图片

消息发送中

重连中

发送失败

数据包结构以及拆包

定义数据包结构

数据包结构定义了每次发送一个数据的完整的数据结构,我们将包体长度定义在包头中来解决粘包和断包的问题。

数据包我们采用了简单的序列化成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

转自https://www.cnblogs.com/qwqwQAQ/p/18330325


该文章在 2024/8/5 10:21:10 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2024 ClickSun All Rights Reserved