马上加入IBC程序猿 各种源码随意下,各种教程随便看! 注册 每日签到 加入编程讨论群

C#教程 ASP.NET教程 C#视频教程程序源码享受不尽 C#技术求助 ASP.NET技术求助

【源码下载】 社群合作 申请版主 程序开发 【远程协助】 每天乐一乐 每日签到 【承接外包项目】 面试-葵花宝典下载

官方一群:

官方二群:

如何巧妙地在基于 TCP Socket 的应用中实现用户注册功能?

[复制链接]
查看2076 | 回复1 | 2019-10-24 09:50:26 | 显示全部楼层 |阅读模式

通常,在基于TCP的应用中(比如我开源的GGTalk即时通讯系统),当TCP毗连建立之后,第一个哀求就是登录哀求,只有登录乐成以后,服务器才会答应客户端进行其它性质的业务哀求。但是,注册用户这个功能比较特别,由于在注册之前,还不存在这个UserID,就更不大概用这个UserID来登录了。

  以是,基于TCP的应用,用户注册功能一般是通过其它方式来实现的,比如,使用WebAPI,或者使用.NET Remoting等技能。

有没有办法可以不使用别的的技能而是直接基于当前的TCP毗连来实现了?

经过我的摸索和实践,找到了一个方法,可以到达这样的效果,而且,即将推出的最新版本的GGTalk接纳了这个方案。 这个方案,就是奥妙使用TCP应用的登录功能,在其基础上加上特别的标记来表达注册举动。

我们先看看GGTalk中的登录功能是怎样做的。

一.现有的登录机制

1.客户端

客户端通过调用IRapidPassiveEngine的Initialize方法来与服务器建立TCP毗连,并发送登录哀求,以及获取登录效果。

  1. // 参数:
  2. // userID:当前登录的用户ID,由数字和字母构成,最大长度为10
  3. // logonPassword:用户登陆暗码。
  4. // serverIP:服务器的IP地址。<br /> // serverPort:服务器的端口。
  5. // customizeHandler:自定义处理器,用于处理服务器或其它用户发送过来的消息
  6. LogonResponse Initialize(string userID, string logonPassword, string serverIP, int serverPort, ICustomizeHandler customizeHandler);
复制代码

参数寄义非常清晰,其返回值LogonResponse的定义如下:

095026tlytljrtjvs070s2.png

LogonResponse的LogonResult属性说明白登录的效果,如果是Failed(登录失败),FailureCause属性就指明白失败的缘故原由。

2.服务端

服务端通过回调IBasicHandler的VerifyUser方法来验证用户的帐号信息。

  1. bool VerifyUser(string systemToken, string userID, string password, out string failureCause);
复制代码

返回的bool值表现验证是否通过,如果返回false(验证不通过,登录失败),则out参数failureCause指明失败的缘故原由,该参数会被返回到客户端为LogonResponse的FailureCause属性赋值。

二.根本思绪

有了上面的基础知识,我们就可以充分使用这个登录机制来实现注册功能了。

我们在服务端和客户端共同做出这样的约定:

(1)当登录的password参数以“#Reg:”开头时,表现当前的举动就不是默认的登录举动,而是注册举动。

由于password一般是MD5加密的,以是不大概以“#Reg:”开头,以是,这样就克制了将正常的登录举动误判为注册举动。

(2)当password参数以“#Reg:”开头,其接下来的内容即表现注册所需的相干信息,各信息之间使用“;”分隔。

比如,GGTalk使用的password的样式如下所示:#Reg:[帐号];[暗码];[名称];[签名]。

举个例子,某个注册的内容为:#Reg:10001;123456;david;加油!

(3)服务端发现当前的登录作为注册举动时,VerifyUser方法一定返回false。而且,注册的效果通过out的failureCause返回给客户端。

(4)客户端以注册举动来使用IRapidPassiveEngine的Initialize方法时,其返回值LogonResponse的LogonResult属性肯定是LogonResult.Failed。

(5)客户端根据返回值LogonResponse的FailureCause属性值来判断注册是乐成还是失败。FailureCause的大概值是:Succeed ,Existed ,Error。

三.详细实现

1.服务端

服务端按如下方式实现IBasicHandler的VerifyUser方法:

  1. public bool VerifyUser(string systemToken, string userID, string password, out string failureCause)
  2. {
  3. <strong>if(password != null && password.StartsWith(RegistActionToken)) //表现是注册
  4. {
  5. //password内容示例: #Reg:10001;123456;david;加油!
  6. failureCause = this.Register(password);
  7. return false</strong><strong>;
  8. }</strong>
  9. <br /> //此处验证帐号暗码...
  10. return true;
  11. }
  12. private static string RegistActionToken = "#Reg:";
  13. private string Register(string content)
  14. {
  15. try
  16. {
  17. //content内容示例: #Reg:10001;123456;david;加油!
  18. string[] parts = content.Substring(RegistActionToken.Length).Split(';');
  19. string id = parts[0];
  20. string pwd = parts[1];
  21. string name = parts[2]; string signature = parts[3];
  22. GGUser user = new GGUser(id, SecurityHelper.MD5String2(pwd), name, signature);
  23. RegisterResult res = this.Register(user); //将注册的用户资料存储到DB
  24. return res.ToString(); //Succeed ,Existed ,Error
  25. }
  26. catch(Exception ee)
  27. {
  28. return "Error: 解析注册字符串报错!" + ee.Message;
  29. }
  30. }
复制代码

代码比较简单,就不再过多解释了。

2.客户端

客户端通过调用IRapidPassiveEngine的Initialize方法来完成注册举动,代码如下所示:

  1. public void Register(string id, string pwd, string name, string signature)
  2. {
  3. string <strong>content</strong> = string.Format("{0}{1};{2};{3};{4}", RegistActionToken, id, pwd, name, signature);
  4. LogonResponse response = rapidPassiveEngine.Initialize("forRegister", <strong>content</strong>, serverIP, serverPort, null);
  5. string result = response.FailureCause; //Succeed ,Existed ,Error
  6. if (result == "Succeed")
  7. {
  8. MessageBox.Show("注册乐成!");
  9. }
  10. else if (result == "Existed")
  11. {
  12. MessageBox.Show("帐号已经存在!");
  13. }
  14. else
  15. {
  16. MessageBox.Show("注册过程中出现错误!");
  17. }
  18. }
复制代码

留意,如果注册乐成,客户端也是还尚未登录到服务器的。

注册乐成之后,再使用乐成注册的帐号和暗码调用正常逻辑的IRapidPassiveEngine的Initialize方法来登录到服务器。

四.结语

云云一来,我们就完全可以使用现有的TCP机制来实现用户的注册,而且在多端(PC、安卓、iOS)都可以这样做。这样就克制了仅仅为了一个注册功能而须要去发布一个Web站点或发布一个Remoting服务(且不说Remoting还没法支持安卓和iOS端),太不划算了。

趁便说一下,GGTalk接下来会不停推出新的版本,不停增强功能,而且UI方面也将进一步美化,敬请期待。







来源:https://www.cnblogs.com/justnow/p/11725110.html
C#论坛 www.ibcibc.com IBC编程社区
C#
C#论坛
IBC编程社区
*滑块验证:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则