zoukankan      html  css  js  c++  java
  • 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 类中定义了许多在其他地方可以直接使用的应用程序级别的逻辑和方法。

    作者:江振宇
    出处:http://jzywh.cnblogs.com
    本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利。
  • 相关阅读:
    POJ:3126-Prime Path
    Linux用户操作及权限
    Web前段开发人员须知的常见浏览器兼容性问题及解决技巧
    windows激活
    未来十年最具有潜力的行业
    WebStorm激活码存储
    5种关系型数据库
    linux常用命令总结
    进程、线程、多线程的总结
    C++类库
  • 原文地址:https://www.cnblogs.com/jzywh/p/2024287.html
Copyright © 2011-2022 走看看