在 c#编写的基于TCP通信的微风IM 版本3 新年新UI 一文中,登陆窗口如下:
登陆等功能是没有问题的,但是“注册新账号”,“找回密码”,“设置”等功能并没有实现,是原来的UI皮肤上自带的。
本文首先来实现“注册新账号功能”
第一步:
打开VS2010 ,找到BasicForm窗体类,这个类是美化窗体的一个基类,我们可以从此窗体继承
第二步,创建新窗体
RegisterUser.cs
把新窗体RegisterUser继承的Form类改成BasicForm类
如下图:
现在新窗体就可以使用BasicForm的样式了,效果如下:
拖入控件,界面如下:
第三步:
先来回顾一下,在数据库中相应的表:
我们知道使用TCP通信的时候,客户端与服务器端进行交互,并不与数据库直接交互,而是由客户端与服务器通信,服务器再和数据库通信。
所以,注册用户的流程就是
(1):客户端注册页面中,通过TCP通信,把用户想要注册“用户ID”,“昵称”,“密码”发送给服务器。
(2) :服务器对发来的”用户ID“进行验证,与数据库交互,判断此”用户ID“是否已经存在,存在则发返回信息给”客户端“,告知其”用户已经存在。
如果“用户ID”符合要求,则插入数据库相关表中,返回消息给“客户端”,告知其注册已经成功
(3):“用户ID”,“昵称”,“密码”需要一个类来存放,我们这里直接使用RcUsers数据表对应的实体类:RcUsers, 此类支持Protobuf.net序列化
(通过TCP通信,在客户端与服务器之间传递数据类,必须把类序列化成二进制数据,对方收到后,再反序列化出来,我们使用网上开源的protobuf.net序列化器。
当然序列化,反序列化的工作是由 开源的networkcomms2.3.1框架帮我们完成的)
![](http://static.oschina.net/uploads/img/201503/03144420_bd2L.gif)
![](http://static.oschina.net/uploads/img/201503/03144420_dJCl.gif)
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using ProtoBuf;
using SimpleIM.Data;
namespace SimpleIM.Business
{
[ProtoContract]
public class RcUsers
{
#region Constructors
public RcUsers()
{ }
#endregion
#region Private Properties
private int id = -1;
private string userID = string.Empty;
private string name = string.Empty;
private string password = string.Empty;
private string declaring = string.Empty;
private int status = -1;
private int groupID = -1;
private bool isMale = false;
private int userLevel = -1;
private bool enabled = false;
private DateTime registerTime = DateTime.UtcNow;
private DateTime lastLoginTime = DateTime.UtcNow;
#endregion
#region Public Properties
[ProtoMember(1)]
public int Id
{
get { return id; }
set { id = value; }
}
[ProtoMember(2)]
public string UserID
{
get { return userID; }
set { userID = value; }
}
[ProtoMember(3)]
public string Name
{
get { return name; }
set { name = value; }
}
[ProtoMember(4)]
public string Password
{
get { return password; }
set { password = value; }
}
[ProtoMember(5)]
public string Declaring
{
get { return declaring; }
set { declaring = value; }
}
[ProtoMember(6)]
public int Status
{
get { return status; }
set { status = value; }
}
[ProtoMember(7)]
public int GroupID
{
get { return groupID; }
set { groupID = value; }
}
[ProtoMember(8)]
public bool IsMale
{
get { return isMale; }
set { isMale = value; }
}
[ProtoMember(9)]
public int UserLevel
{
get { return userLevel; }
set { userLevel = value; }
}
[ProtoMember(10)]
public bool Enabled
{
get { return enabled; }
set { enabled = value; }
}
[ProtoMember(11)]
public DateTime RegisterTime
{
get { return registerTime; }
set { registerTime = value; }
}
[ProtoMember(12)]
public DateTime LastLoginTime
{
get { return lastLoginTime; }
set { lastLoginTime = value; }
}
#endregion
}
}
RCUsers类是由CodeSmith模板生成的, 可以参见本博客关于CodeSmith的其他相应文章
NetworkComms网络通信框架配套CodeSmith模板使用简介 模板下载地址: 【模板下载】分享我所使用的数据库框架
我们在微风IM中,使用的存储过程,数据层代码,实体类,逻辑层代码都是通过使用CodeSmith模板生成的(添加功能,需要做对应的修改),极大的提高了工作效率。
言归正传,我们开始进行注册相关的开发:
客户端代码:
//定义一个契约类 用于传递相关的信息给服务器
RcUsers currentUser = new RcUsers();
//给属性赋值
currentUser.UserID = txtUserID.Text.Trim();
currentUser.Password = txtPsw.Text.Trim();
currentUser.Name = txtNickName.Text.Trim();
//同步方法 传递并序列化契约类到服务器,并从获取获取返回的信息 (返回的信息类型为ResMessage)
//RegUser 发送的消息类型
//ResRegUser 接收返回的消息类型
ResMessage regContract = Common.TcpConn.SendReceiveObject<ResMessage>("RegUser", "ResRegUser", 8000, currentUser);
if (regContract.Message == "注册成功")
{
BasicMsgBoxForm form = new BasicMsgBoxForm("注册成功", "信息窗口", MessageBoxButtons.OK, MessageBoxIcon.None);
form.StartPosition = FormStartPosition.CenterScreen;
form.ShowDialog();
txtNickName.Text = "";
txtUserID.Text = "";
txtPsw.Text = "";
txtRePsw.Text = "";
}
else
{
BasicMsgBoxForm form = new BasicMsgBoxForm(regContract.Message, "信息窗口", MessageBoxButtons.OK, MessageBoxIcon.Error);
form.StartPosition = FormStartPosition.CenterScreen;
form.ShowDialog();
}
![](http://static.oschina.net/uploads/img/201503/03144420_JVUD.jpg)
using System;
using System.Collections.Generic;
using System.Text;
using ProtoBuf;
namespace SimpleIM.Business
{
//操作结果的返回信息,可通用
[ProtoContract]
public class ResMessage
{
[ProtoMember(1)]
public string Message;
public ResMessage() { }
public ResMessage(string message)
{
this.Message = message;
}
}
}
服务器端相应的代码:
//注册新用户
NetworkComms.AppendGlobalIncomingPacketHandler<RcUsers>("RegUser", IncomingRegisterUser);
//注册新用户
private void IncomingRegisterUser(PacketHeader header, Connection connection, RcUsers contract)
{
try
{
//声明一个契约类 用于返回数据给客户端
ResMessage resMessage = new ResMessage();
//判断用户是否存在
RcUsers user = DoRcUsers.GetByUserID(contract.UserID);
if (user .Id>-1)
{
//如果存在,在不进行数据库操作,直接返回信息给客户端
resMessage.Message = "用户ID已经存在";
}
else
{
//如果不存在,则添加用户到数据库中
//修改一下用户的相关信息,暂时手工设定一下,您可根据情况修改
contract.Declaring = "春暖花开";
contract.Status = -1;
contract.IsMale = true;
contract.UserLevel = 1;
contract.Enabled = false;
contract.RegisterTime = DateTime.Now;
contract.LastLoginTime = DateTime.Now;
contract.GroupID = 115;
//添加用户到数据库中
DoRcUsers.Save(contract);
resMessage.Message = "注册成功";
}
//返回信息给客户端端
connection.SendObject("ResRegUser", resMessage);
}
catch (Exception ex)
{
LogTools.LogException(ex, "IncomingChangePsw");
}
}
效果图如下:
现在主页面上就能够看到新注册的用户了