一、GFF简介

GFF是仿QQ界面,通信基于SAEA.MessageSocket、SAEA.Http、SAEA.MVC实现包含客户端和服务器的程序,源码完全公开,项目源码地址:https://github.com/yswenli/GFF ,大家可以去我的github了解,欢迎follow,star与fork。

GFF消息采用高性能基于IOCP模型的tcp实现,文件采用http实现,代码简洁,一目了然,非常适合想要了解聊天通信关键技术的朋友。

二、运行界面

GFF已实现了消息、表情、图片、截图等关键功能,已编译的绿色版https://github.com/yswenli/GFF/releases下载下来后运行如下图:

三、关键技术

1.界面采用了CSkin的一套QQ皮肤,更多的可以百度一下CSkin相关的资料,或者查看GFF的源码。

2.客户端通信使用了SAEA.MessageSocket的封装类MessageHelper,代码非常简洁,不到100行代码,轻松实现通信。

 /*****************************************************************************************************
* 本代码版权归Wenli所有,All Rights Reserved (C) 2015-2016
*****************************************************************************************************
* 所属域:WENLI-PC
* 登录用户:Administrator
* CLR版本:4.0.30319.17929
* 唯一标识:20da4241-0bdc-4a06-8793-6d0889c31f95
* 机器名称:WENLI-PC
* 联系人邮箱:wenguoli_520@qq.com
*****************************************************************************************************
* 命名空间:MCITest * 创建年份:2015
* 创建时间:2015-12-02 11:15:24
* 创建人:Wenli
* 创建说明:
*****************************************************************************************************/ using GFF.Component.Config;
using SAEA.MessageSocket;
using System;
using System.Net;
using System.Text;
using System.Threading.Tasks; namespace GFFClient
{
public class MessageHelper
{
public delegate void OnErrorHander(Exception ex, string msg); public delegate void OnMessageHanndle(string channelID, string msg); private static readonly object lockObj = new object(); private string _channelID; private string _userName; ClientConfig clientConfig; public MessageHelper()
{
clientConfig = ClientConfig.Instance();
} /// <summary>
/// Tcp客户端
/// </summary>
public MessageClient Client { get; private set; } public void Start(string userName, string channelID)
{
_userName = userName;
_channelID = channelID; Client = new MessageClient(, clientConfig.IP, clientConfig.Port);
Client.OnChannelMessage += Client_OnChannelMessage;
Client.OnPrivateMessage += Client_OnPrivateMessage;
Client.OnError += Client_OnError;
Client.Connect();
Client.Login();
Client.Subscribe(channelID);
} private void Client_OnError(string ID, Exception ex)
{
OnError.Invoke(ex, ex.Message);
} private void Client_OnChannelMessage(SAEA.MessageSocket.Model.Business.ChannelMessage msg)
{
OnMessage?.Invoke(_channelID, msg.Content);
} private void Client_OnPrivateMessage(SAEA.MessageSocket.Model.Business.PrivateMessage msg)
{
OnMessage?.Invoke(msg.Receiver, msg.Content);
} public void Publish(string channelID, string value)
{
Client.SendChannelMsg(channelID, value);
} public void SendFile(string channelID, string fileName, Action<string> callBack)
{
HttpSendFileAsync(fileName, url => { callBack?.Invoke(url); });
} public void HttpSendFileAsync(string fileName, Action<string> callBack)
{
Task.Run(() =>
{
using (WebClient webClient = new WebClient())
{
var url = clientConfig.Url + Encoding.UTF8.GetString(webClient.UploadFile(clientConfig.Url + "Upload", fileName));
callBack.Invoke(url);
}
});
} public void Stop()
{
try
{
Client.Dispose();
}
catch { }
} public event OnMessageHanndle OnMessage; public event OnErrorHander OnError;
}
}

3.服务端使用SAEA.MessageSocket实现服务端消息处理逻辑、SAEA.MVC实现文件处理逻辑,有兴趣的朋友可以在此基础上实现更多实际业务。

 /*****************************************************************************************************
* 本代码版权归Wenli所有,All Rights Reserved (C) 2015-2016
*****************************************************************************************************
* 所属域:WENLI-PC
* 登录用户:Administrator
* CLR版本:4.0.30319.17929
* 唯一标识:20da4241-0bdc-4a06-8793-6d0889c31f95
* 机器名称:WENLI-PC
* 联系人邮箱:wenguoli_520@qq.com
*****************************************************************************************************
* 命名空间:MCITest * 创建年份:2015
* 创建时间:2015-12-02 11:15:24
* 创建人:Wenli
* 创建说明:
*****************************************************************************************************/ using GFF.Component.Config;
using GFF.Helper;
using SAEA.MessageSocket;
using SAEA.MVC;
using SAEA.Sockets.Interface;
using System; namespace GFFServer
{
internal class Program
{
private static MessageServer messageServer; private static SAEAMvcApplication mvcApplication; private static void Main(string[] args)
{
Console.Title = "GFFServer"; ConsoleHelper.WriteLine("正在初始化消息服务器...", ConsoleColor.Green);
messageServer = new MessageServer();
messageServer.OnAccepted += Server_OnAccepted;
messageServer.OnError += Server_OnError;
messageServer.OnDisconnected += Server_OnDisconnected;
ConsoleHelper.WriteLine("消息服务器初始化完毕...", ConsoleColor.Green); ConsoleHelper.WriteLine("正在初始化文件服务器...", ConsoleColor.DarkYellow);
var filePort = ServerConfig.Instance().FilePort;
mvcApplication = new SAEAMvcApplication(port: filePort);
mvcApplication.SetDefault("File", "Test");
ConsoleHelper.WriteLine("文件服务器初始化完毕,http://127.0.0.1:" + filePort + "/...", ConsoleColor.DarkYellow); ConsoleHelper.WriteLine("正在启动消息服务器...", ConsoleColor.Green);
messageServer.Start();
ConsoleHelper.WriteLine("消息服务器启动完毕...", ConsoleColor.Green); ConsoleHelper.WriteLine("正在启动文件服务器...", ConsoleColor.DarkYellow);
mvcApplication.Start();
ConsoleHelper.WriteLine("文件服务器启动完毕...", ConsoleColor.DarkYellow); ConsoleHelper.WriteLine("点击回车,结束服务");
Console.ReadLine();
} private static void Server_OnDisconnected(string ID, Exception ex)
{
ConsoleHelper.WriteInfo(string.Format("客户端{0}已断开连接,当前连接数共记:{1}", ID, messageServer.ClientCounts));
} private static void Server_OnError(string ID, Exception ex)
{
ConsoleHelper.WriteErr(ex);
} private static void Server_OnAccepted(IUserToken userToken)
{
ConsoleHelper.WriteInfo(string.Format("客户端{0}已连接,当前连接数共记:{1}", userToken.ID, messageServer.ClientCounts));
}
}
}
 using SAEA.MVC;
using System.IO; namespace GFFServer.Controllers
{
/// <summary>
/// 文件处理
/// </summary>
public class FileController : Controller
{
public ActionResult Test()
{
return Content("GFF File Server");
} [HttpPost]
public ActionResult Upload()
{
var postFile = HttpContext.Request.PostFiles[];
var filePath = HttpContext.Server.MapPath("/Files");
if (!Directory.Exists(filePath)) Directory.CreateDirectory(filePath);
filePath = Path.Combine(filePath, postFile.FileName);
System.IO.File.WriteAllBytes(filePath, postFile.Data);
return Content("Download?fileName=" + postFile.FileName);
} public ActionResult Download(string fileName)
{
var filePath = Path.Combine(HttpContext.Server.MapPath("/Files"), fileName);
return File(filePath);
}
}
}

四、项目结构

1.GFF.Component 封装客户的截图、聊天展现、表情、配置等

2.GFF.Helper 封装了GFF项目中需要使用的一些工具类

3.GFF.Model 是GFF中使用到类、接口、枚举等

4.GFFClient 是GFF的客户端主体项目

5.GFFServer 是GFF的服务端主体项目

转载请标明本文来源:https://www.cnblogs.com/yswenli/p/6274526.html
更多内容欢迎我的的github:https://github.com/GFF
如果发现本文有什么问题和任何建议,也随时欢迎交流~

 

GFF高仿QQ客户端及服务器的更多相关文章

  1. 高仿QQ的即时通讯应用带服务端软件安装

    Android 基于xmpp协议,smack包,openfire服务端(在下面)的高仿QQ的即时通讯实现.实现了注册,登录,读取好友列表,搜索好友,添加分组,添加好友,删除好友,修改心情,两个客户端之 ...

  2. 史上最简单,一步集成侧滑(删除)菜单,高仿QQ、IOS。

    重要的话 开头说,not for the RecyclerView or ListView, for the Any ViewGroup. 本控件不依赖任何父布局,不是针对 RecyclerView. ...

  3. Android实现高仿QQ附近的人搜索展示

    本文主要实现了高仿QQ附近的人搜索展示,用到了自定义控件的方法 最终效果如下 1.下面展示列表我们可以使用ViewPager来实现(当然如果你不觉得麻烦,你也可以用HorizontalScrollVi ...

  4. 高仿QQ即时聊天软件开发系列之三登录窗口用户选择下拉框

    上一篇高仿QQ即时聊天软件开发系列之二登录窗口界面写了一个大概的布局和原理 这一篇详细说下拉框的实现原理 先上最终效果图 一开始其实只是想给下拉框加一个placeholder效果,让下拉框在未选择未输 ...

  5. 高仿QQ即时聊天软件开发系列之二登录窗口界面

    继上一篇高仿QQ即时聊天软件开发系列之一开端之后,开始做登录窗口 废话不多说,先看效果,只有界面 可能还有一些细节地方没有做,例如那个LOGO嘛,不要在意这些细节 GIF虽短,可是这做起来真难,好吧因 ...

  6. 高仿QQ即时聊天软件开发系列之一开端

    前段时间在园子里看到一个大神做了一个GG2014IM软件,仿QQ的,那感觉···,赶快下载源码过来试试,还真能直接跑起来,效果也不错.但一看源码,全都给封装到了ESFramework里面了,音视频那部 ...

  7. 高仿qq聊天界面

    高仿qq聊天界面,给有需要的人,界面效果如下: 真心觉得做界面非常痛苦,给有需要的朋友. chat.xml <?xml version="1.0" encoding=&quo ...

  8. WPF ”真正的“高仿QQ

    时常可以在各种论坛 博客 看到 各种所谓的 高仿QQ. 说实话 越看越想笑呢.(PS:纯粹的 抨击 那些 不追求 UI 完美主义者) 例如:       本次模仿 采用 C# WPF XAML , 总 ...

  9. 安卓高仿QQ头像截取升级版

    观看此篇文章前,请先阅读上篇文章:高仿QQ头像截取: 本篇之所以为升级版,是在截取头像界面添加了与qq类似的阴影层(裁剪区域以外的部分),且看效果图:   为了适应大家不同需求,这次打了两个包,及上图 ...

随机推荐

  1. Ubuntu16.04下postgresql-10

      这里使用源码安装的方式进行: Linux版本:ubuntu16.04 PostgresSQL版本:postgresql-10.3 在PostgreSQL官网下载地址:https://www.pos ...

  2. 智能POS打印配置&常见问题FAQ 12-14 后期持续更新

    1.安卓一体机会员注销钱会不会退回到支付宝 智能pos会员注销钱目前只能现金退还. 2.支付异常订单悬浮球在哪关闭 设置-->功能设置-->系统设置-->开启支付异常订单悬浮球 3. ...

  3. pjsip 播放音视频

    http://blog.csdn.net/leixiaohua1020/article/details/40246783 onCallMediaState回调里,解码方向,获取ci.media[i]. ...

  4. Using IntelliJ IDEA as the Vim Editor

    转载自https://www.jetbrains.com/help/idea/using-intellij-idea-as-the-vim-editor.html This feature is on ...

  5. tesseract安装及问题处理

    错误1 pytesseract.pytesseract.TesseractNotFoundError: tesseract is not installed or it's not in your p ...

  6. c/c++ static关键字

    static关键字 1,static 成员变量 static 成员变量不随着对象的创建而开辟内存空间.也就是说,不管从哪个对象去看static成员变量,都是一样的. 2, static 成员方法 st ...

  7. Servlet(三):获取表单数据、解决乱码和报错问题

    在了解了servlet的生命周期以及运行过程后,再来动手写一个小例子,加深对servlet的理解. 一.需求说明 在用户注册信息页面,输入用户名.密码.性别.邮箱等一些信息后,页面返回刚刚填写的信息. ...

  8. 谱聚类算法(Spectral Clustering)优化与扩展

    谱聚类(Spectral Clustering, SC)在前面的博文中已经详述,是一种基于图论的聚类方法,简单形象且理论基础充分,在社交网络中广泛应用.本文将讲述进一步扩展其应用场景:首先是User- ...

  9. vuex最简单的

    https://segmentfault.com/a/1190000009404727 "dependencies": {    "axios": " ...

  10. (转)Spring Boot(十八):使用 Spring Boot 集成 FastDFS

    http://www.ityouknow.com/springboot/2018/01/16/spring-boot-fastdfs.html 上篇文章介绍了如何使用 Spring Boot 上传文件 ...