GFF高仿QQ客户端及服务器
一、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客户端及服务器的更多相关文章
- 高仿QQ的即时通讯应用带服务端软件安装
Android 基于xmpp协议,smack包,openfire服务端(在下面)的高仿QQ的即时通讯实现.实现了注册,登录,读取好友列表,搜索好友,添加分组,添加好友,删除好友,修改心情,两个客户端之 ...
- 史上最简单,一步集成侧滑(删除)菜单,高仿QQ、IOS。
重要的话 开头说,not for the RecyclerView or ListView, for the Any ViewGroup. 本控件不依赖任何父布局,不是针对 RecyclerView. ...
- Android实现高仿QQ附近的人搜索展示
本文主要实现了高仿QQ附近的人搜索展示,用到了自定义控件的方法 最终效果如下 1.下面展示列表我们可以使用ViewPager来实现(当然如果你不觉得麻烦,你也可以用HorizontalScrollVi ...
- 高仿QQ即时聊天软件开发系列之三登录窗口用户选择下拉框
上一篇高仿QQ即时聊天软件开发系列之二登录窗口界面写了一个大概的布局和原理 这一篇详细说下拉框的实现原理 先上最终效果图 一开始其实只是想给下拉框加一个placeholder效果,让下拉框在未选择未输 ...
- 高仿QQ即时聊天软件开发系列之二登录窗口界面
继上一篇高仿QQ即时聊天软件开发系列之一开端之后,开始做登录窗口 废话不多说,先看效果,只有界面 可能还有一些细节地方没有做,例如那个LOGO嘛,不要在意这些细节 GIF虽短,可是这做起来真难,好吧因 ...
- 高仿QQ即时聊天软件开发系列之一开端
前段时间在园子里看到一个大神做了一个GG2014IM软件,仿QQ的,那感觉···,赶快下载源码过来试试,还真能直接跑起来,效果也不错.但一看源码,全都给封装到了ESFramework里面了,音视频那部 ...
- 高仿qq聊天界面
高仿qq聊天界面,给有需要的人,界面效果如下: 真心觉得做界面非常痛苦,给有需要的朋友. chat.xml <?xml version="1.0" encoding=&quo ...
- WPF ”真正的“高仿QQ
时常可以在各种论坛 博客 看到 各种所谓的 高仿QQ. 说实话 越看越想笑呢.(PS:纯粹的 抨击 那些 不追求 UI 完美主义者) 例如: 本次模仿 采用 C# WPF XAML , 总 ...
- 安卓高仿QQ头像截取升级版
观看此篇文章前,请先阅读上篇文章:高仿QQ头像截取: 本篇之所以为升级版,是在截取头像界面添加了与qq类似的阴影层(裁剪区域以外的部分),且看效果图: 为了适应大家不同需求,这次打了两个包,及上图 ...
随机推荐
- 企业建立成功 DevOps 模式所需应对的5个挑战
[编者按]本文作者为 Kevin Goldberg,主要介绍要想成功部署 DevOps 模式,企业所需应对的5大挑战与问题.文章系国内 ITOM 管理平台 OneAPM 编译呈现. 要给 DevOps ...
- 使用IEDriverServer.exe驱动IE11,实现自动化测试
+ 下载IEDriverServer http://dl.pconline.com.cn/download/771640-1.html 解压缩得到IEDriverServer.e ...
- SQL Server如何定位自定义标量函数被那个SQL调用次数最多浅析
前阵子遇到一个很是棘手的问题,监控系统DPA发现某个自定义标量函数被调用的次数非常高,高到一个离谱的程度.然后在Troubleshooting这个问题的时候,确实遇到了一些问题让我很是纠结,下文是解决 ...
- 洗礼灵魂,修炼python(84)-- 知识拾遗篇 —— 网络编程之socket
学习本篇文章的前提,你需要了解网络技术基础,请参阅我的另一个分类的博文:网络互联技术(4)——计算机网络常识.原理剖析 网络通信要素 1.IP地址: 用来标识网络上一台独立的终端(PC或者主机) ip ...
- 【MM系列】SAP MB1A MB1B MB1C MB11 MIGO的区别解析
公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[MM系列]SAP MB1A MB1B MB1C ...
- hivesql优化的深入解析
转载:https://www.csdn.net/article/2015-01-13/2823530 一个Hive查询生成多个Map Reduce Job,一个Map Reduce Job又有Map, ...
- 编写脚本实现DHCP服务与DHCP中继自动化执行
编写脚本实现DHCP服务与DHCP中继自动化执行 本脚本是在liunx搭建DHCP服务器以及DHCP中继服务器实验环境下实现的https://www.cnblogs.com/yuzly/p/10539 ...
- LeetCode算法题-Number of 1 Bits(Java实现)
这是悦乐书的第186次更新,第188篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第45题(顺位题号是191).编写一个带无符号整数的函数,并返回它所具有的"1 ...
- LeetCode算法题-Palindrome Linked List(Java实现)
这是悦乐书的第196次更新,第202篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第58题(顺位题号是234).给出一个单链表,确定它是否是回文.例如: 输入:1-> ...
- 面试总结——JVM篇
前言:该篇主要对Java虚拟机相关的题目进行介绍. JVM篇 基本上在面试的时候,都会或多或少的涉及JVM,主要看面试官的侧重点,笔者在面试过程中,是通过volatile问题,引导了JVM相关问题上的 ...