SuperSocket服务器架设(四):我的AppSession连接管理方案(简单版)
1. AppSession连接管理的用处:
a) 服务器向客户端批量推送信息
b) 客户端对客户端的通信
2. 创建客户端管理类MySessionManager,添加静态列表SessionList
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
namespace SuperSocketApp1
{
/// <summary>
/// MySession对应连接储存类
/// </summary>
public static class MySessionManager
{
public static List<MySession> SessionList = new List<MySession>();
}
}3. SessionList的添加与移除方法1:
a) 在MySession的OnSessionStarted()方法中添加如下代码
MySessionManager.SessionList.Add(this);
b) 在MySession的OnSessionClosed()方法中添加如下代码
MySessionManager.SessionList.Remove(this);
4. SessionList的添加与移除方法2:
a) 在MyServer的OnNewSessionConnected()方法中添加如下代码
MySessionManager.SessionList.Add(session);
b) 在MyServer的OnSessionClosed()方法中添加如下代码
MySessionManager.SessionList.Remove(session);
5. 向客户端推送消息的代码可以自由发挥,比如以自定义命令的方式实现:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SuperSocket.SocketBase;
using SuperSocket.SocketBase.Command;
using SuperSocket.SocketBase.Protocol;
namespace SuperSocketApp1
{
/// <summary>
/// 向客户端推送信息
/// </summary>
public class PUSH : CommandBase<MySession, StringRequestInfo>
{
public override void ExecuteCommand(MySession session, StringRequestInfo requestInfo)
{
/*
* 内置命令行协议:
* 命令行协议定义了每个请求必须以回车换行结尾 "
"。
* 用空格来分割请求的Key和参数
* requestInfo.Body 参数
* requestInfo.Parameters 用空格分隔参数,返回数组
*/
foreach (MySession tmp in MySessionManager.SessionList)
{
tmp.Send(requestInfo.Body);
}
}
}
}6. 客户端间的通信过程为:获取客户端列表,选择客户端并发送消息(这里通过自定义命令实现)
a) 获取客户端列表:创建LIST命令,代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SuperSocket.SocketBase;
using SuperSocket.SocketBase.Command;
using SuperSocket.SocketBase.Protocol;
namespace SuperSocketApp1
{
public class LIST : CommandBase<MySession, StringRequestInfo>
{
/// <summary>
/// 获取客户端列表
/// </summary>
/// <param name="session"></param>
/// <param name="requestInfo"></param>
public override void ExecuteCommand(MySession session, StringRequestInfo requestInfo)
{
var tmp = "";
//判断clentList中是否有值
if (MySessionManager.SessionList.Count < 1)
{
tmp = "NoBody.";
}
else
{
for (int i = 0; i < MySessionManager.SessionList.Count; i++)
{
//SessionID为Session的唯一标示
tmp += "Id:" + (i + 1) + ",SessionID:" + MySessionManager.SessionList[i].SessionID;
}
}
session.Send(tmp);
}
}
}b) 选择客户端并发送消息:创建SEND命令,代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SuperSocket.SocketBase;
using SuperSocket.SocketBase.Command;
using SuperSocket.SocketBase.Protocol;
namespace SuperSocketApp1
{
/// <summary>
/// 向客户端推送信息
/// </summary>
public class SEND : CommandBase<MySession, StringRequestInfo>
{
public override void ExecuteCommand(MySession session, StringRequestInfo requestInfo)
{
/*
* 内置命令行协议:
* 命令行协议定义了每个请求必须以回车换行结尾 "
"。
* 用空格来分割请求的Key和参数
* requestInfo.Body 参数
* requestInfo.Parameters 用空格分隔参数,返回数组
*/
//通过参数的个数判断命令类型
if (requestInfo.Parameters.Length < 2)
{
session.Send("命令格式:send id 信息");
//send 信息
//for (int i = 0; i < Client.clientList.Count; i++)
//{
// //取SessionId对应的Session并发送信息
// Client.TestServer.GetAppSessionByID(Client.clientList[i]).Send(requestInfo.Body);
//}
}
else
{
//send id 信息
//判断id是否合法
if (int.Parse(requestInfo.Parameters[0]) < 1 || int.Parse(requestInfo.Parameters[0]) > MySessionManager.SessionList.Count)
{
session.Send("id错误。");
}
else
{
int i = int.Parse(requestInfo.Parameters[0]);
//取Session并发送信息
MySessionManager.SessionList[i - 1].Send(requestInfo.Parameters[1]);
}
}
}
}
}7. 目录结构:
8. MyServer和MySession最终代码:
a) MyServer代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SuperSocket.SocketBase;
using SuperSocket.SocketBase.Config;
namespace SuperSocketApp1
{
/// <summary>
/// 自定义服务器类MyServer,继承AppServer,并传入自定义连接类MySession
/// </summary>
public class MyServer : AppServer<MySession>
{
protected override void OnStartup()
{
base.OnStartup();
Console.WriteLine("服务器已启动");
}
/// <summary>
/// 输出新连接信息
/// </summary>
/// <param name="session"></param>
protected override void OnNewSessionConnected(MySession session)
{
base.OnNewSessionConnected(session);
//客户端建立连接,将session加入list
MySessionManager.SessionList.Add(session);
Console.Write("
" + session.LocalEndPoint.Address.ToString() + ":连接");
}
/// <summary>
/// 输出断开连接信息
/// </summary>
/// <param name="session"></param>
/// <param name="reason"></param>
protected override void OnSessionClosed(MySession session, CloseReason reason)
{
base.OnSessionClosed(session, reason);
//客户端断开连接,移除session
MySessionManager.SessionList.Remove(session);
Console.Write("
" + session.LocalEndPoint.Address.ToString() + ":断开连接");
}
protected override void OnStopped()
{
base.OnStopped();
Console.WriteLine("服务器已停止");
}
}
}b) MySession代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SuperSocket;
using SuperSocket.Common;
using SuperSocket.SocketBase;
using SuperSocket.SocketBase.Protocol;
namespace SuperSocketApp1
{
/// <summary>
/// 自定义连接类MySession,继承AppSession,并传入到AppSession
/// </summary>
public class MySession : AppSession<MySession>
{
/// <summary>
/// 新连接
/// </summary>
protected override void OnSessionStarted()
{
MySessionManager.SessionList.Add(this);
Console.WriteLine(this.LocalEndPoint.Address.ToString());
this.Send("
Hello User");
}
/// <summary>
/// 未知的Command
/// </summary>
/// <param name="requestInfo"></param>
protected override void HandleUnknownRequest(StringRequestInfo requestInfo)
{
this.Send("
未知的命令");
}
/// <summary>
/// 捕捉异常并输出
/// </summary>
/// <param name="e"></param>
protected override void HandleException(Exception e)
{
this.Send("
异常: {0}", e.Message);
}
/// <summary>
/// 连接关闭
/// </summary>
/// <param name="reason"></param>
protected override void OnSessionClosed(CloseReason reason)
{
MySessionManager.SessionList.Remove(this);
base.OnSessionClosed(reason);
}
}
}9. 注:AppServer类自带方法GetAllSessions()用于获取所有的AppSession:
a) AppServer中:
foreach (var session in this.GetAllSessions())
{
session.Send(now);
}
b) 其他地方:
foreach (var session in AppServer.GetAllSessions())
{
session.Send(now);
}a) MyServer代码:
声明:该文观点仅代表作者本人,入门客AI创业平台信息发布平台仅提供信息存储空间服务,如有疑问请联系rumenke@qq.com。
- 上一篇:没有了
- 下一篇:没有了
