基于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 ...
随机推荐
- 基于docker一键化部署LNMP环境
cd / && wget https://files.cnblogs.com/files/superlinux/install_lnmp.sh && bash inst ...
- 发现了一个膨胀样式的css库
众所周知,对于前端来说css是最难的了,如果你遇到了一个脑洞大奇思妙想的产品,那就更难了. 很不巧,了不起就经受过这样的痛苦,产品经理看了HarmonyOS4的发布会,脑子一热就让设计师出了一套膨胀蓬 ...
- NOIP模拟100(多校32)
T1 饥饿的狐狸 解题思路 贪心签到题. 最小值的做法就是对于温度比水小的从大到小吃,然后喝一口水,然后把剩下的从小到大吃掉. 最大值的做法,几乎就是大的挑一个小的挑一个间隔着吃,可以排完序之后双指针 ...
- CSP-S2023 题解
CSP-S 2023 题解 密码锁 发现总状态数只有 \(10^5\) 个,枚举 \(O(n)\) 暴力判断即可,复杂度 \(O(10^5 n)\). 或者每一个状态只对应了 \(81\) 个状态,枚 ...
- 编程语言界的丐帮 C#.NET 国密数字信封 民生银行
民生银行的库DLL只有C版本和JAVA版本.按着JAVA版本做的C# 实现. 重点内容. 1.数字信封就是 CmsEnvelopedData Der编码后转BASE64 2.重点类:ContentIn ...
- 比较 SpringSecurity 和 Shiro
相比 Spring Security, Shiro 在保持强大功能的同时,使用简单性和灵活性. SpringSecurity: 即使是一个一个简单的请求, 最少得经过它的 8 个Filter.Spri ...
- Android 中的 perfboot工具
背景 开机首先加载bootloader,由bootloader启动kernel,然后运行init程序,有init启动Zygote,Zygote进程启动SystemServ进程,在SystemServe ...
- android 8.1 安全机制 — SEAndroid & SELinux
android 8.1 安全机制 - SEAndroid & SELinux 原文链接:https://blog.csdn.net/qq_19923217/article/details/81 ...
- 为什么有些IP无法PING通但又能访问
背景 在调试板子的网络,突然发现板子无法ping通开发机(出现request timed out,),而电脑却可以ping通板子. 而scp.ssh以及nfs等工具却可以正常使用. 原理 找了一些资料 ...
- 移动web布局方法
继续更新移动端的一个布局,这也是经典中的经典,当初只知道个rem和vwvh适配,其实这里面还有很多的门道不只是一个适配这么简单 一.前置 1.背景缩放 我们都知道做移动端,给的图都是二倍图,你拿来用直 ...