一、websocket的搭建(还没有实现序列化的功能)
功能不是太完整,并且有些地方逻辑有点乱,但是基本的登录、注册已经实现,排行没有实现。现在问题是,发送回前端的数据没有序列化,只是发送字符串。
1、实现前后端的连接
WebSocketServer ws = new WebSocketServer();
#region 注销
//ws.NewMessageReceived += new SessionHandler<WebSocketSession, string>(ReceiveMessages);
//ws.NewSessionConnected += new SessionHandler<WebSocketSession>(ReceiveConnect);
//ws.SessionClosed += new SessionHandler<WebSocketSession, CloseReason>(SessionClosed);
//ws.NewDataReceived += new SessionHandler<WebSocketSession, byte[]>( ReceiveData);
#endregion
if (!ws.Setup("192.168.0.134", 2018))//IP要和本机相同,否则会报错
{
Console.WriteLine("Failed to setup!"); //未设置成功
Console.ReadKey();
return;
}
if (!ws.Start())
{
Console.WriteLine("Failed to start!");
Console.ReadKey();
return;//未启动成功
}
Console.WriteLine("The server started successfully, press key 'q' to stop it!");
ws.NewMessageReceived += ReceiveMessages;
ws.NewSessionConnected += ReceiveConnect;
ws.SessionClosed += SessionClosed;
ws.NewDataReceived += ReceiveData;
//如果不是"q",则继续执行
while (Console.ReadKey().KeyChar != 'q')
{
Console.WriteLine();
continue;
}
//Stop the appServer
ws.Stop();
Console.WriteLine("The server was stopped!");
Console.ReadKey();
}
2、包装各类方法
1>实现握手功能
static void ReceiveConnect(WebSocketSession session)
{
Console.WriteLine("新的连接,即为握手包");
SendToClient(session, "欢迎新用户");
}
2>监听用户退出
static void SessionClosed(WebSocketSession session, CloseReason closeReason)
{
lock (_dicLock)
{
string key = string.Empty;
foreach (KeyValuePair<string, WebSocketSession> keyValue in _dic)
{
if (keyValue.Value.Equals(session))
{
key = keyValue.Key;
break;
}
}
if (key != string.Empty)
{
_dic.Remove(key);
}
}
Console.WriteLine("已经退出");
}
3>接收前端二进制数据,同时实现注册、登录、排行的功能(功能实现方法可能有些不合理,视自己情况而定,而且判断功能是哪个的方法也不是太准确,可以适当调整)
static void ReceiveData(WebSocketSession session, byte[] data)
{
if (data == null || data.Length < 4)
{
return;
}
//string s = BitConverter.ToString(data,4,data.Length-4);
uint len = BitConverter.ToUInt32(data, 0);
int a = len.ToString().Length;//包的长度
//获取数组的前面四位之后得信息,用来识别前端给的判断信息
byte[] k = new byte[data.Length - 4];
Array.Copy(data, 4, k, 0, data.Length - 4);
//前面四位数组
byte[] w = new byte[4];
Array.Copy(data, 0, w, 0, 4);
MemoryStream msg = new MemoryStream(data);
//通过这步,主要是获取t.status得值,用来判断实现哪个功能,因为注册、登录、排行.proto中都有status对象
log1 t = ProtoBuf.Serializer.Deserialize<log1>(msg);
//byte[] j = new byte[1];
//Array.Copy(data, 3, j, 0, 1);
if (t.status == "1001")
{
if (a + sizeof(uint) <= data.Length) //长度符合
{
logins.log1 m = new logins.log1();
MemoryStream ms = new MemoryStream(data);
//BinaryReader br = new BinaryReader(ms);
//ushort protoId = br.ReadUInt16(); //协议号
//Type type = typeof(uint); //通过协议号获取
log1 o = ProtoBuf.Serializer.Deserialize<log1>(ms);//反序列化
#region 登录信息
logins.log1 h = (logins.log1)o;
UserLoginManage ii = new UserLoginManage();
//调用BLL里面方法,用来判断是否符合要求
if (ii.UserLogin(h) != null)
{
SendToClient(session, "1001");//登录成功
Console.WriteLine("1001登录成功");
}
else
{
SendToClient(session, "1002");//登录失败
Console.WriteLine("1002登录失败");
}
Console.ReadKey();
}
}
#endregion
#region 注册信息
if (t.status == "1002")
{
if (a + sizeof(uint) <= data.Length) //长度符合
{
MemoryStream ms = new MemoryStream(k);
BinaryReader br = new BinaryReader(ms);
//ushort protoId = br.ReadUInt16(); //协议号
//Type type = typeof(uint); //通过协议号获取
reg o = ProtoBuf.Serializer.Deserialize<reg>(ms);//反序列化
register.reg rr = new register.reg();
string sql = "select name from dbUserRegister where name='{0}'";
sql = string.Format(sql, o.userid);
SqlDataReader objReader = SQLHelper.GetReader(sql);
if (objReader.Read())
{
rr.userid = objReader["name"].ToString();
objReader.Close();
}
if (rr.userid != null)
{
SendToClient(session, "1006");//注册失败,用户名已被占用
Console.WriteLine("1006用户名已经被占用");
}
else
{
UserRegisterManage hh = new UserRegisterManage();
//判断是否有输入信息
if (hh.UserRegister(o) != null)
{
SendToClient(session,"1003");//注册成功,有输入信息
Console.WriteLine("1003注册成功,有输入信息");
}
else
{
SendToClient(session, "1004");//注册失败,没有注册信息
Console.WriteLine("1004注册失败,没有注册信息");
}
Console.ReadLine();
}
}
}
#endregion
#region 排行信息
if (t.status == "1003")
{
if (a + sizeof(uint) <= data.Length) //长度符合
{
MemoryStream ms = new MemoryStream(k);
BinaryReader br = new BinaryReader(ms);
//ushort protoId = br.ReadUInt16(); //协议号
//Type type = typeof(uint); //通过协议号获取
Msg.data o = ProtoBuf.Serializer.Deserialize<Msg.data>(ms);//反序列化
Msg.data ss = (Msg.data)o;
Msg.data uu = new Msg.data();
string sqlc = "select score from dbUserRanking where score='{0}'";
sqlc = string.Format(sqlc, ss.score);
SqlDataReader objReader = SQLHelper.GetReader(sqlc);
if (objReader.Read())
{
UserRankingManage nn = new UserRankingManage();
string sqld = "select top 3 score from dbUserRanking order by score";
SqlDataReader objRead = SQLHelper.GetReader(sqld);
if (objRead.Read())
{
List<Msg.data> list = new List<Msg.data>();
while (objRead.NextResult())//读取出所有东西
{
Msg.data dd = new Msg.data
{
score = objRead["score"].ToString()
};
list.Add(dd);
}
byte[] bytes = new byte[1024];
MemoryStream mem = new MemoryStream(bytes);
ProtoBuf.Serializer.NonGeneric.Serialize(mem, list);
long position = mem.Position;
SendToClient(session, typeof(int), bytes, 0, (int)position);
}
}
}
#endregion
}
}
4>发送string类型数据给客户端(没有区分是哪种消息)
static void SendToClient(WebSocketSession session,string msg)
{
session.Send(msg);
}
5>通过协议头来发送消息(后来没有通过协议头获取,二十通过protobuf接收前面定义的头信息)
static void SendToClient(WebSocketSession session, Type type,
byte[] msg, int offset, int length)
{
MemoryStream ms = new MemoryStream(msg);
BinaryWriter br = new BinaryWriter(ms);
uint protoId = 0; //通过type获取协议号
br.Write(protoId); //写入头
int len = (int)ms.Length;
br.Write(length + sizeof(uint)); //写入头
session.Send(msg, offset, length + sizeof(uint) + sizeof(int));
}
6>群发消息,发给多个客户端
static void SendToClient(List<WebSocketSession> sessions, string msg)
{
foreach (WebSocketSession session in sessions)
{
session.Send(msg);
}
}
static void SendToClient(List<WebSocketSession> sessions, byte[] msg, int offset, int length)
{
foreach (WebSocketSession session in sessions)
{
session.Send(msg, offset, length);
}
}
.proto设计:https://blog.csdn.net/qq_42375267/article/details/84567626