GFF高仿QQ客户端及服务器
程序员文章站
2022-05-14 08:26:07
一、GFF简介 GFF是仿QQ界面,通信基于SAEA.MessageSocket、SAEA.Http、SAEA.MVC实现包含客户端和服务器的程序,源码完全公开,项目源码地址:https://github.com/yswenli/GFF ,大家可以去我的github了解,欢迎follow,star与 ......
一、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行代码,轻松实现通信。
1 /***************************************************************************************************** 2 * 本代码版权归wenli所有,all rights reserved (c) 2015-2016 3 ***************************************************************************************************** 4 * 所属域:wenli-pc 5 * 登录用户:administrator 6 * clr版本:4.0.30319.17929 7 * 唯一标识:20da4241-0bdc-4a06-8793-6d0889c31f95 8 * 机器名称:wenli-pc 9 * 联系人邮箱:wenguoli_520@qq.com 10 ***************************************************************************************************** 11 * 命名空间:mcitest 12 13 14 * 创建年份:2015 15 * 创建时间:2015-12-02 11:15:24 16 * 创建人:wenli 17 * 创建说明: 18 *****************************************************************************************************/ 19 20 using gff.component.config; 21 using saea.messagesocket; 22 using system; 23 using system.net; 24 using system.text; 25 using system.threading.tasks; 26 27 namespace gffclient 28 { 29 public class messagehelper 30 { 31 public delegate void onerrorhander(exception ex, string msg); 32 33 public delegate void onmessagehanndle(string channelid, string msg); 34 35 private static readonly object lockobj = new object(); 36 37 private string _channelid; 38 39 private string _username; 40 41 clientconfig clientconfig; 42 43 public messagehelper() 44 { 45 clientconfig = clientconfig.instance(); 46 } 47 48 /// <summary> 49 /// tcp客户端 50 /// </summary> 51 public messageclient client { get; private set; } 52 53 public void start(string username, string channelid) 54 { 55 _username = username; 56 _channelid = channelid; 57 58 client = new messageclient(10240, clientconfig.ip, clientconfig.port); 59 client.onchannelmessage += client_onchannelmessage; 60 client.onprivatemessage += client_onprivatemessage; 61 client.onerror += client_onerror; 62 client.connect(); 63 client.login(); 64 client.subscribe(channelid); 65 } 66 67 private void client_onerror(string id, exception ex) 68 { 69 onerror.invoke(ex, ex.message); 70 } 71 72 private void client_onchannelmessage(saea.messagesocket.model.business.channelmessage msg) 73 { 74 onmessage?.invoke(_channelid, msg.content); 75 } 76 77 private void client_onprivatemessage(saea.messagesocket.model.business.privatemessage msg) 78 { 79 onmessage?.invoke(msg.receiver, msg.content); 80 } 81 82 public void publish(string channelid, string value) 83 { 84 client.sendchannelmsg(channelid, value); 85 } 86 87 88 public void sendfile(string channelid, string filename, action<string> callback) 89 { 90 httpsendfileasync(filename, url => { callback?.invoke(url); }); 91 } 92 93 94 public void httpsendfileasync(string filename, action<string> callback) 95 { 96 task.run(() => 97 { 98 using (webclient webclient = new webclient()) 99 { 100 var url = clientconfig.url + encoding.utf8.getstring(webclient.uploadfile(clientconfig.url + "upload", filename)); 101 callback.invoke(url); 102 } 103 }); 104 } 105 106 public void stop() 107 { 108 try 109 { 110 client.dispose(); 111 } 112 catch { } 113 } 114 115 public event onmessagehanndle onmessage; 116 117 public event onerrorhander onerror; 118 } 119 }
3.服务端使用saea.messagesocket实现服务端消息处理逻辑、saea.mvc实现文件处理逻辑,有兴趣的朋友可以在此基础上实现更多实际业务。
1 /***************************************************************************************************** 2 * 本代码版权归wenli所有,all rights reserved (c) 2015-2016 3 ***************************************************************************************************** 4 * 所属域:wenli-pc 5 * 登录用户:administrator 6 * clr版本:4.0.30319.17929 7 * 唯一标识:20da4241-0bdc-4a06-8793-6d0889c31f95 8 * 机器名称:wenli-pc 9 * 联系人邮箱:wenguoli_520@qq.com 10 ***************************************************************************************************** 11 * 命名空间:mcitest 12 13 14 * 创建年份:2015 15 * 创建时间:2015-12-02 11:15:24 16 * 创建人:wenli 17 * 创建说明: 18 *****************************************************************************************************/ 19 20 using gff.component.config; 21 using gff.helper; 22 using saea.messagesocket; 23 using saea.mvc; 24 using saea.sockets.interface; 25 using system; 26 27 namespace gffserver 28 { 29 internal class program 30 { 31 private static messageserver messageserver; 32 33 private static saeamvcapplication mvcapplication; 34 35 private static void main(string[] args) 36 { 37 console.title = "gffserver"; 38 39 40 consolehelper.writeline("正在初始化消息服务器...", consolecolor.green); 41 messageserver = new messageserver(); 42 messageserver.onaccepted += server_onaccepted; 43 messageserver.onerror += server_onerror; 44 messageserver.ondisconnected += server_ondisconnected; 45 consolehelper.writeline("消息服务器初始化完毕...", consolecolor.green); 46 47 48 49 consolehelper.writeline("正在初始化文件服务器...", consolecolor.darkyellow); 50 var fileport = serverconfig.instance().fileport; 51 mvcapplication = new saeamvcapplication(port: fileport); 52 mvcapplication.setdefault("file", "test"); 53 consolehelper.writeline("文件服务器初始化完毕,http://127.0.0.1:" + fileport + "/...", consolecolor.darkyellow); 54 55 56 57 consolehelper.writeline("正在启动消息服务器...", consolecolor.green); 58 messageserver.start(); 59 consolehelper.writeline("消息服务器启动完毕...", consolecolor.green); 60 61 62 63 consolehelper.writeline("正在启动文件服务器...", consolecolor.darkyellow); 64 mvcapplication.start(); 65 consolehelper.writeline("文件服务器启动完毕...", consolecolor.darkyellow); 66 67 68 69 consolehelper.writeline("点击回车,结束服务"); 70 console.readline(); 71 } 72 73 private static void server_ondisconnected(string id, exception ex) 74 { 75 consolehelper.writeinfo(string.format("客户端{0}已断开连接,当前连接数共记:{1}", id, messageserver.clientcounts)); 76 } 77 78 private static void server_onerror(string id, exception ex) 79 { 80 consolehelper.writeerr(ex); 81 } 82 83 private static void server_onaccepted(iusertoken usertoken) 84 { 85 consolehelper.writeinfo(string.format("客户端{0}已连接,当前连接数共记:{1}", usertoken.id, messageserver.clientcounts)); 86 } 87 } 88 }
1 using saea.mvc; 2 using system.io; 3 4 namespace gffserver.controllers 5 { 6 /// <summary> 7 /// 文件处理 8 /// </summary> 9 public class filecontroller : controller 10 { 11 public actionresult test() 12 { 13 return content("gff file server"); 14 } 15 16 [httppost] 17 public actionresult upload() 18 { 19 var postfile = httpcontext.request.postfiles[0]; 20 var filepath = httpcontext.server.mappath("/files"); 21 if (!directory.exists(filepath)) directory.createdirectory(filepath); 22 filepath = path.combine(filepath, postfile.filename); 23 system.io.file.writeallbytes(filepath, postfile.data); 24 return content("download?filename=" + postfile.filename); 25 } 26 27 28 public actionresult download(string filename) 29 { 30 var filepath = path.combine(httpcontext.server.mappath("/files"), filename); 31 return file(filepath); 32 } 33 } 34 }
四、项目结构
1.gff.component 封装客户的截图、聊天展现、表情、配置等
2.gff.helper 封装了gff项目中需要使用的一些工具类
3.gff.model 是gff中使用到类、接口、枚举等
4.gffclient 是gff的客户端主体项目
5.gffserver 是gff的服务端主体项目
转载请标明本文来源:
更多内容欢迎我的的github:https://github.com/gff
如果发现本文有什么问题和任何建议,也随时欢迎交流~