服务端创建协议

首先在SimpleServer项目中的ProtocolEnum中添加新的协议类型

1
2
3
4
5
6
7
8
9
10
public enum ProtocolEnum
{
None = 0,
MsgSecret = 1,//密钥协议
MsgPing = 2,//心跳包协议
MsgRegister = 3,//注册协议++
MsgLogin = 4,//登录协议++

MsgTest = 9999
}

然后在SimpleServer项目的Proto文件夹内新建LoginMsg文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
using ProtoBuf;
using SimpleServer.Business;

[ProtoContract()]
public class MsgRegister : MsgBase
{
public MsgRegister()
{
ProtoType = ProtocolEnum.MsgRegister;
}
[ProtoMember(1)]
public override ProtocolEnum ProtoType { get; set; }
[ProtoMember(2)]
public string? Account;
[ProtoMember(3)]
public string? Password;
[ProtoMember(4)]
public string? Code;//这个是验证码,这里先写下
[ProtoMember(5)]
public RegisterType RegisterType;

[ProtoMember(6)]
public RegisterResult Result;
}
[ProtoContract()]
public class MsgLogin : MsgBase
{
public MsgLogin()
{
ProtoType = ProtocolEnum.MsgLogin;
}
[ProtoMember(1)]
public override ProtocolEnum ProtoType { get; set; }
[ProtoMember(2)]
public string? Account;
[ProtoMember(3)]
public string? Password;
[ProtoMember(4)]
public LoginType LoginType;

[ProtoMember(5)]
public LoginResult Result;
[ProtoMember(6)]
public string? token;
}

所有协议的枚举写在ProtocolEnum里,具体的协议类可以分开在不同的文件中,比如SysMsg文件存储的是心跳包和私钥的协议类,这里的LoginMsg存储的都是注册登录相关的协议

服务端处理协议

修改MsgHandler

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
/// <summary>
/// 分发注册请求
/// </summary>
public static void MsgRegister(ClientSocket client, MsgBase msg)
{
if (msg == null)
{
Debug.LogError(client.Socket?.RemoteEndPoint?.ToString() + "MsgRegister协议接收错误!");
}
else
{
MsgRegister msgRegister = (MsgRegister)msg;
var rst = UserManager.Instance.Register(msgRegister.RegisterType, msgRegister.Account, msgRegister.Password, out string token);
msgRegister.Account = null;
msgRegister.Password = null;
msgRegister.Result = rst;
ServerSocket.Send(client, msgRegister);
}
}
/// <summary>
/// 分发登录请求
/// </summary>
public static void MsgLogin(ClientSocket client, MsgBase msg)
{
if (msg == null)
{
Debug.LogError(client.Socket?.RemoteEndPoint?.ToString() + "MsgLogin协议接收错误!");
}
else
{
MsgLogin msgLogin = (MsgLogin)msg;
var rst = UserManager.Instance.Login(msgLogin.LoginType, msgLogin.Account, msgLogin.Password, out int userId, out string token);
msgLogin.Account = null;
msgLogin.Password = null;
msgLogin.Result = rst;
msgLogin.token = token;
client.UserId = userId;
ServerSocket.Send(client, msgLogin);
}

}

修改ClientSocket,记录当前客户端在数据库的ID

1
2
3
4
5
6
7
8
9
10
11
12
13
using System.Net.Sockets;

namespace SimpleServer.Net
{
public class ClientSocket
{
public Socket? Socket { get; set; }
public long LastPingTime { get; set; }

public ByteArray ReadBuff = new ByteArray();
public int UserId { get; set; } = 0;//+++
}
}

客户端处理协议

将LoginMsg.cs拷贝到客户端Scripts——Net——Proto文件夹内(将里面的表示可空的问号删去),将ServerEnum.cs拷贝到客户端Scripts——Net文件夹内

修改客户端的ProtocolEnum

1
2
3
4
5
6
7
8
9
10
public enum ProtocolEnum
{
None = 0,
MsgSecret = 1,//密钥协议
MsgPing = 2,//心跳包协议
MsgRegister = 3,
MsgLogin = 4,

MsgTest = 9999,//分包测试
}

修改客户端的ProtocolManager

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
/// <summary>
/// 请求注册
/// </summary>
/// <param name="registerType">注册类型</param>
/// <param name="userName">用户名</param>
/// <param name="password">密码</param>
/// <param name="code">验证码</param>
/// <param name="callBack">注册结果的回调</param>
public static void RegisterRequest(RegisterType registerType,string userName,string password,string code,System.Action<RegisterResult> callBack)
{
MsgRegister msg = new MsgRegister();
NetManager.Instance.AddProtoListener(ProtocolEnum.MsgRegister, (msg) =>
{
MsgRegister msgRegister = msg as MsgRegister;
callBack?.Invoke(msgRegister.Result);
});
msg.Account = userName;
msg.Password = password;
msg.Code = code;
NetManager.Instance.SendMessage(msg);
}
/// <summary>
/// 请求登录
/// </summary>
/// <param name="loginType">登录方式</param>
/// <param name="userName">用户名</param>
/// <param name="password">密码</param>
/// <param name="callBack">登录回调,包含新token</param>
public static void LoginRequest(LoginType loginType, string userName, string password, System.Action<LoginResult,string> callBack)
{
MsgLogin msg = new MsgLogin();
NetManager.Instance.AddProtoListener(ProtocolEnum.MsgLogin, (msg) =>
{
MsgLogin msgLogin = msg as MsgLogin;
callBack?.Invoke(msgLogin.Result,msgLogin.token);
});
msg.Account = userName;
msg.Password = password;
msg.LoginType = loginType;
NetManager.Instance.SendMessage(msg);
}

NetTest中直接测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
void Update()
{
NetManager.Instance.Update();
if (Input.GetKeyDown(KeyCode.K))
{
ProtocolManager.SocketTest();
}
if (Input.GetKeyDown(KeyCode.S))//+++
{
ProtocolManager.RegisterRequest(
RegisterType.Phone,
"15698756452",
"zwt67674",
"330545",
(res) =>
{
if(res == RegisterResult.AlreadyExist)
{
Debug.LogError("该手机号已经注册过了");
}
else if (res == RegisterResult.WrongCode)
{
Debug.LogError("验证码错误");
}
else if(res == RegisterResult.Forbidden)
{
Debug.LogError("该账户存在问题,请联系客服!");
}
else if(res == RegisterResult.Failed)
{
Debug.LogError("网络错误");
}
else
{
Debug.Log("注册成功");
}
});
}
if(Input.GetKeyDown(KeyCode.A))//+++
{
ProtocolManager.LoginRequest(
LoginType.Phone,
"15698756452",
"zwt67674",
(res, token) =>
{
if(res == LoginResult.UserNotExist)
{
Debug.LogError("未找到该用户");
}
else if(res == LoginResult.WrongPwd)
{
Debug.LogError("密码错误");
}
else if(res == LoginResult.TimeoutToken)
{
Debug.LogError("请重新登录");
}
else if (res == LoginResult.Failed)
{
Debug.LogError("网络错误");
}
else
{
Debug.Log("登录成功");
}
});
}
}