SuperSocket 1.4系列文档(3) 使用SuperSocket的第一步,实现你自己的AppServer和AppSession
什么是AppSession?
AppSession 代表一个和客户端的逻辑连接,基于连接的操作应该定于在该类之中。你可以用该类的实例发送数据到客户端,接收客户端发送的数据或者关闭连接。
什么是AppServer?
AppServer 代表了监听客户端连接,承载TCP连接的服务器实例。理想情况下,我们可以通过AppServer实例获取任何你想要的客户端连接,服务器级别的操作和逻辑应该定义在此类之中。
创建你的AppSession
现在,我们以EchoServer为例:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SuperSocket.SocketBase;
namespace SuperSocket.QuickStart.EchoService
{
public class EchoSession : AppSession<EchoSession>
{
public override void StartSession()
{
SendResponse("Welcome to EchoServer!");
}
public override void HandleExceptionalError(Exception e)
{
SendResponse("Server side error occurred!");
}
}
}
在此示例之中,EchoSession为我们做了两件事情:
1. 当客户端连接上时,发送欢迎信息到客户端;
2. 当命令执行的时抛出异常,发送消息"Server side error occurred!"到客户端。
创建你的AppServer
我们还是以EchoServer 为例:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SuperSocket.SocketBase;
namespace SuperSocket.QuickStart.EchoService
{
public class EchoServer : AppServer<EchoSession>
{
}
}
你的AppServer实现需要一个AppSession的类型作为泛型参数用于继承基类AppServer.因为EchoServer不需要额外的逻辑,所以不需要写任何代码在该类之中。
然后我们再以BroadcastServer 为例:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using SuperSocket.Common;
using SuperSocket.SocketBase;
using SuperSocket.SocketBase.Command;
namespace SuperSocket.QuickStart.BroadcastService
{
public class BroadcastServer : AppServer<BroadcastSession>
{
private Dictionary<string, List<string>> broadcastDict = new Dictionary<string, List<string>>(StringComparer.OrdinalIgnoreCase);
private object broadcastSyncRoot = new object();
private Dictionary<string, BroadcastSession> broadcastSessionDict = new Dictionary<string, BroadcastSession>(StringComparer.OrdinalIgnoreCase);
private object syncRoot = new object();
public BroadcastServer()
{
lock (broadcastSyncRoot)
{
//It means that device V001 will receive broadcast messages from C001 and C002,
//device V002 will receive broadcast messages from C002 and C003
broadcastDict["C001"] = new List<string> { "V001" };
broadcastDict["C002"] = new List<string> { "V001", "V002" };
broadcastDict["C003"] = new List<string> { "V002" };
}
}
internal void RegisterNewSession(BroadcastSession session)
{
if (string.IsNullOrEmpty(session.DeviceNumber))
return;
lock (syncRoot)
{
broadcastSessionDict[session.DeviceNumber] = session;
}
}
internal void RemoveOnlineSession(BroadcastSession session)
{
if (string.IsNullOrEmpty(session.DeviceNumber))
return;
lock (syncRoot)
{
broadcastSessionDict.Remove(session.DeviceNumber);
}
}
internal void BroadcastMessage(BroadcastSession session, string message)
{
List<string> targetDeviceNumbers;
lock (broadcastSyncRoot)
{
if(!broadcastDict.TryGetValue(session.DeviceNumber, out targetDeviceNumbers))
return;
}
if (targetDeviceNumbers == null || targetDeviceNumbers.Count <= 0)
return;
List<BroadcastSession> sessions = new List<BroadcastSession>();
lock (syncRoot)
{
BroadcastSession s;
foreach(var key in targetDeviceNumbers)
{
if (broadcastSessionDict.TryGetValue(key, out s))
sessions.Add(s);
}
}
Async.Run(() =>
{
sessions.ForEach(s => s.SendResponse(message));
});
}
protected override void OnAppSessionClosed(object sender, AppSessionClosedEventArgs<BroadcastSession> e)
{
RemoveOnlineSession(e.Session);
base.OnAppSessionClosed(sender, e);
}
}
}
此时,我们可以发现BroadcastServer 类中定义了许多在其他地方可以直接使用的应用程序级别的逻辑和方法。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架