基于EasyTcp4Net开发一个功能较为完善的去持久化聊天软件
之前自己写了一篇介绍TCP的一些常用的功能介绍和特征,并且用代码做了示例,最终开发了一个EasyTcp4Net的TCP工具库,其最大的特色就是使用了微软提供的高性能库中的一些数据结构来处理TCP数据。
最近辞职待业在家,也没啥事做,就利用自己写的TCP通讯库基础上开发了一个示例的聊天程序,功能包括,文本发送,图片发送,断线重连,消息发送成功确认,消息发送失败提示等。
示例
发消息给自己
收到消息
发送图片
消息发送中
重连中
发送失败
数据包结构以及拆包
定义数据包结构
数据包结构定义了每次发送一个数据的完整的数据结构,我们将包体长度定义在包头中来解决粘包和断包的问题。
数据包我们采用了简单的序列化成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
基于EasyTcp4Net开发一个功能较为完善的去持久化聊天软件的更多相关文章
- 基于SpringBoot开发一个Restful服务,实现增删改查功能
前言 在去年的时候,在各种渠道中略微的了解了SpringBoot,在开发web项目的时候是如何的方便.快捷.但是当时并没有认真的去学习下,毕竟感觉自己在Struts和SpringMVC都用得不太熟练. ...
- 基于线程开发一个FTP服务器
一,项目题目:基于线程开发一个FTP服务器 二,项目要求: 基本要求: 1.用户加密认证 2.允许同时多用户登录 3.每个用户有自己的家目录 ,且只能访问自己的家目录 4.对用户进行磁盘配 ...
- 整合了一个功能强大完善的OA系统源码,php全开源 界面漂亮美观
整合了一个功能强大完善的OA系统源码,php全开源界面漂亮美观.需要的同学联系Q:930948049
- 使用EF+ASP.NET MVC+Bootstrap开发一个功能强大的问卷调查系统
功能简介 支持七大题型 下拉选择题.单选题.多选题.填空题.数字题.问答题.组合/矩阵题(单选组合.多选组合.填空组合.数字组合) 题库支持 每个问卷都要设置姓名.年龄.性别.学历,怎么办?题库帮您轻 ...
- 基于SOUI开发一个简单的小工具
基于DriectUI有很多库,比如 Duilib (免费) soui (免费) DuiVision (免费) 炫彩 (界面库免费,UI设计器付费,不提供源码) skinui (免费使用,但不开放源码, ...
- 【玩转开源】BananaPi R2 —— 第三篇 基于Openwrt开发一个简单的路由器
上一篇讲解了R2的网口配置,这一篇我们以BananaPi R2为例子来实现一个简单的路由器:那么一个简单的路由器应该具备什么样的功能呢?最简单的说就是wan+lan+ap这三个功能. 首先wan+la ...
- 成都开发一个app大概好多钱?
目前,移动APP已成为很多小企业业务销售的新渠道之一,于是问题来了,一般想到要开发一个自己的app,就想问:开发一个app好多钱?去百度.360.搜狗等等平台去找相关的app开发公司咨询或者问问朋友有 ...
- 基于c++11新标准开发一个支持多线程高并发的网络库
背景 新的c++11标准出后,c++语法得到了非常多的扩展,比起以往不论什么时候都要灵活和高效,提高了程序编码的效率,为软件开发者节省了不少的时间. 之前我也写过基于ACE的网络server框架,但A ...
- 基于.NetCore开发博客项目 StarBlog - (13) 加入友情链接功能
系列文章 基于.NetCore开发博客项目 StarBlog - (1) 为什么需要自己写一个博客? 基于.NetCore开发博客项目 StarBlog - (2) 环境准备和创建项目 基于.NetC ...
- 用VSCode开发一个基于asp.net core 2.0/sql server linux(docker)/ng5/bs4的项目(1)
最近使用vscode比较多. 学习了一下如何在mac上使用vscode开发asp.netcore项目. 这里是我写的关于vscode的一篇文章: https://www.cnblogs.com/cgz ...
随机推荐
- statefulset有状态应用管理
statefulset介绍 StatefulSet(有状态集,缩写为sts)常用于部署有状态的且需要有序启动的应用程序,比如在进行SpringCloud项目容器化时,Eureka的部署是比较适合用St ...
- Linux命令行优化,历史记录优化
#命令行优化: echo "export PS1='\[\033[01;31m\]\u\[\033[00m\]@\[\033[01;32m\]\h\[\033[00m\][\[\033[01 ...
- 震惊!docker镜像还有这些知识,你都知道吗?----镜像(二)
镜像查看 查看镜像 [root@hmm-docker ~]# docker images REPOSITORY#镜像仓库 TAG #标签 IMAGE ID#镜像id CREATED #创建时间 SIZ ...
- kettle从入门到精通 第二十三课 kettle carte 错误(java.lang.OutOfMemoryError: GC overhead limit exceeded,Could not emit buffer due to lack of requests,java heap space)分析
1.Could not emit buffer due to lack of requests(无法发出缓冲区,因为请求不足.) 原因有两点:1)消费者处理数据能力较弱,如表输出步骤.2)消费者没有处 ...
- ChatGPT应用与实践初探
近期,长江商学院EMBA38期&甄知科技开展了题为"ChatGPT应用与实践初探"的线下沙龙活动,由上海甄知科技创始合伙人兼CTO张礼军主讲,主要给大家解密最近很火的Cha ...
- ISO pod 使用
pod 安装 相关依赖包 新建podfile 文件 pod init 编辑podfile文件添加第三方库 // pod '第三方依赖库名', '版本号' pod 'SDWebImageSwiftUI' ...
- springboot增加@EnableAsync注解,否则方法中的@Async注解没有生效
springboot增加@EnableAsync注解,否则方法中的@Async注解没有生效. @EnableFeignClients(basePackages = {"com.test&qu ...
- Sealos 5.0 正式发布,云本应该是操作系统
把所有资源抽象成一个整体,一切皆应用,这才是云应该有的样子. 2018 年 8 月 15 日 Sealos 提交了第一行代码. 随后开源社区以每年翻倍的速度高速增长. 2022 年我们正式创业,经历一 ...
- 01-Linux系统介绍、安装与入门
关于Linux 背景 最先出现的是Unix操作系统,这种操作系统收费,而且适用于大型机上面. Linus想做一个免费的,传播自由的操作系统.他就仿照Unix的操作,做了一个类Unix系统:Linux内 ...
- Java开发者的神经网络进阶指南:深入探讨交叉熵损失函数
前言 今天来讲一下损失函数--交叉熵函数,什么是损失函数呢?大体就是真实与预测之间的差异,这个交叉熵(Cross Entropy)是Shannon信息论中一个重要概念,主要用于度量两个概率分布间的差异 ...