之前自己写了一篇介绍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开发一个功能较为完善的去持久化聊天软件的更多相关文章

  1. 基于SpringBoot开发一个Restful服务,实现增删改查功能

    前言 在去年的时候,在各种渠道中略微的了解了SpringBoot,在开发web项目的时候是如何的方便.快捷.但是当时并没有认真的去学习下,毕竟感觉自己在Struts和SpringMVC都用得不太熟练. ...

  2. 基于线程开发一个FTP服务器

    一,项目题目:基于线程开发一个FTP服务器 二,项目要求: 基本要求: 1.用户加密认证   2.允许同时多用户登录   3.每个用户有自己的家目录 ,且只能访问自己的家目录   4.对用户进行磁盘配 ...

  3. 整合了一个功能强大完善的OA系统源码,php全开源 界面漂亮美观

    整合了一个功能强大完善的OA系统源码,php全开源界面漂亮美观.需要的同学联系Q:930948049

  4. 使用EF+ASP.NET MVC+Bootstrap开发一个功能强大的问卷调查系统

    功能简介 支持七大题型 下拉选择题.单选题.多选题.填空题.数字题.问答题.组合/矩阵题(单选组合.多选组合.填空组合.数字组合) 题库支持 每个问卷都要设置姓名.年龄.性别.学历,怎么办?题库帮您轻 ...

  5. 基于SOUI开发一个简单的小工具

    基于DriectUI有很多库,比如 Duilib (免费) soui (免费) DuiVision (免费) 炫彩 (界面库免费,UI设计器付费,不提供源码) skinui (免费使用,但不开放源码, ...

  6. 【玩转开源】BananaPi R2 —— 第三篇 基于Openwrt开发一个简单的路由器

    上一篇讲解了R2的网口配置,这一篇我们以BananaPi R2为例子来实现一个简单的路由器:那么一个简单的路由器应该具备什么样的功能呢?最简单的说就是wan+lan+ap这三个功能. 首先wan+la ...

  7. 成都开发一个app大概好多钱?

    目前,移动APP已成为很多小企业业务销售的新渠道之一,于是问题来了,一般想到要开发一个自己的app,就想问:开发一个app好多钱?去百度.360.搜狗等等平台去找相关的app开发公司咨询或者问问朋友有 ...

  8. 基于c++11新标准开发一个支持多线程高并发的网络库

    背景 新的c++11标准出后,c++语法得到了非常多的扩展,比起以往不论什么时候都要灵活和高效,提高了程序编码的效率,为软件开发者节省了不少的时间. 之前我也写过基于ACE的网络server框架,但A ...

  9. 基于.NetCore开发博客项目 StarBlog - (13) 加入友情链接功能

    系列文章 基于.NetCore开发博客项目 StarBlog - (1) 为什么需要自己写一个博客? 基于.NetCore开发博客项目 StarBlog - (2) 环境准备和创建项目 基于.NetC ...

  10. 用VSCode开发一个基于asp.net core 2.0/sql server linux(docker)/ng5/bs4的项目(1)

    最近使用vscode比较多. 学习了一下如何在mac上使用vscode开发asp.netcore项目. 这里是我写的关于vscode的一篇文章: https://www.cnblogs.com/cgz ...

随机推荐

  1. 莫烦tensorflow学习记录 (6)卷积神经网络 CNN (Convolutional Neural Network)

    卷积 和 神经网络 莫烦大佬的原文章https://mofanpy.com/tutorials/machine-learning/tensorflow/intro-CNN/ 我的理解就是千层饼,鸡蛋烧 ...

  2. 改变函数中的this指向

      // 改变函数的this指向         // 先记住一句话 : 箭头函数不能改变this指向         // 语法1: call() 方法         //        在调用函 ...

  3. ETL工具-nifi干货系列 第七讲 处理器JoltTransformJSON(续)

    第六讲教程只简单介绍了Jolt的chain转换模式,本节课介绍下Jolt的各种转换模式. 点击的处理器JoltTransformJSON高级配置选项,进行测试Jolt的转换模式. 1.Cardinal ...

  4. springboot项目编译时,使用自定义注解类找不到符号

    springboot项目编译时,使用自定义注解类找不到符号 Java项目编译时,使用自定义注解类找不到符号Spring-boot项目编辑器:idea问题:编译时找不到符号.项目中用到了自定义注解类.编 ...

  5. 实训day2

    HTML基本介绍 编辑网页的语言,超文本标记语言,是迄今为止网络上应用最为广泛的语言,也是抱成网页文档的主要语言.HTML文本是由HTML命令组成的描述性文本,HTML命令可以说明文字.图形.动画.声 ...

  6. ubuntu 安装 arm-none-eabi-gcc 的几种方式

    背景 这篇文章主要是为了解决 在 Linux 中 编译 能够在 裸机上 跑的 程序 目前许多嵌入式软件软件开发在Linux平台下进行,编译效率高很多,如今天所述的gcc-arm-none-eabi常适 ...

  7. ETL服务器连接GaussDB(DWS)集群客户端配置

    问题描述:给ETL的服务器上安装gsql的工具,用来连接GaussDB(DWS)集群,做数据抽取用 DWS:GaussDB(DWS) 8.2.1-ESL 1.获取软件包 登录FusionInsight ...

  8. NXP i.MX 6ULL工业开发板硬件说明书( ARM Cortex-A7,主频792MHz)

    前  言 本文档主要介绍TLIMX6U-EVM评估板硬件接口资源以及设计注意事项等内容. 创龙科技TLIMX6U-EVM是一款基于NXP i.MX 6ULL的ARM Cortex-A7高性能低功耗处理 ...

  9. Vue2 整理(二):核心篇(组件化开发)

    前言 上一篇连接:vue2 整理:基础篇. 组件化开发 组件概念 组件,对于学Java的人来说的话,这个词所要表达的意思再熟悉不过了. 所谓组件就是:面向对象中的抽象.封装思想:而所谓的组件化就是:把 ...

  10. Node.js中的模块

    CommonJS模块 CommonJS是一种规范,它定义了JavaScript 在服务端运行所必备的基础能力,比如:模块化.IO.进程管理等.其中,模块化方案影响深远,其对模块的定义如下: 1,模块引 ...