登陆窗口如下:
本文首先来实现“注册新账号功能”
第一步:
打开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框架帮我们完成的)
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类
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(); }
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"); } }
效果图如下:
现在主页面上就能够看到新注册的用户了