wcf 会话模式如何遍历所有会话。

飞翔的薄荷 2015-04-29 11:19:03
管理员可以强制用户下线,如何遍历会话,并强制会话关闭。
...全文
181 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
如何使用while语句,如何声明static变量,如何声明一个事件,如何在一个窗口里调用另一个窗口,这些都是编程时学习的。 应该先把“注册、登录、退出”的业务逻辑流程搞清楚了,再考虑如何编程的问题。所以那类纯编程的术语不会过早提及。如果你没有提出一个业务逻辑流程,却开始纠结“单例模式”这种名词儿了,肯定会停滞不前的。
  • 打赏
  • 举报
回复
另外要说一下,所谓“单例模式”这类东西跟这里的业务设计无关。设计模式通常都是相当肤浅的编程技巧部分,就好象你学习“如何使用while语句,如何声明一个static变量”一样。虽然你在实现一个业务逻辑程序时一定会用到“while语句、static变量”之类的编程知识的,但是这些概念不应该干扰你进行业务逻辑设计。它们是不同层次的东西,你完全可以先忘记那些编程术语、先把逻辑设计搞好。 而当你设计一个既有数据结构又有操作流程操作时序的应用,你会发现,用设计模式的雷人名词儿对你的设计往往是一个干扰。比如说上述的“会话编号以及相关数据实体”不管保存在哪里,这都是业务逻辑。跟是不是单例模式完全无关的,《设计模式》那本书上的20几种模式的层次太低,而了解具体的业务流程设计才是高层次的模式。
  • 打赏
  • 举报
回复
引用 4 楼 ml232528 的回复:
如果要实现,客户端注册、登陆、强制下线等功能。wcf的服务应该怎么设计。是单例模式,还是应该用会话模式。
简单说,你可以在你的wcf服务中设计一个“登录”功能,它返回一个随机产生的“授权编号”,例如是一个guid编号。客户端首先需要调用这个登录功能进行登录,获取会话编号。以后的几乎所有wcf服务也都必须同时以编号作为参数之一。 可以在你的服务器端保存每一个授权编号对应的“用户名、用户密码、最后一次访问服务器的时间、最近5分钟使用过的ip(这通常都是异步登记的,而不是在每一次处理客户端服务请求时同步记录)、购物车,等等信息。按照你的业务需要而设计。 而“注册”功能恰好是为数很少不需要提供这个编号的调用之一。注册与登录、在线其实是无关的。 由于wcf是无状态的,服务器不可能知道、也不关心客户端是否随时在线。你只能通过“最后一次访问服务器的时间”来判断客户端是否疑似离线。因此通常要求客户端定时(例如最长间隔3分钟)发一个简单的“心跳消息”。 你的wcf服务要“强制下线”一个会话,其实就是在自己的列表中删除对应的编号的记录。客户端得不到任何通知。
飞翔的薄荷 2015-04-30
  • 打赏
  • 举报
回复
引用 2 楼 starfd 的回复:
session模式不是asp.net里面的session……
我是客户端、服务器模式,跟网页无关。
飞翔的薄荷 2015-04-30
  • 打赏
  • 举报
回复
引用 1 楼 sp1234 的回复:
不能遍历。你需要自己重新设计所谓的“在线”机制。
如果要实现,客户端注册、登陆、强制下线等功能。wcf的服务应该怎么设计。是单例模式,还是应该用会话模式。
周美文 2015-04-30
  • 打赏
  • 举报
回复
把连接断掉,并给客户端发送信号,使它强制下线
ccm1818168 2015-04-30
  • 打赏
  • 举报
回复
这方面的机制 我总是用跟 Socket 类似的方法
software_artisan 2015-04-30
  • 打赏
  • 举报
回复
上面的代码的作用有: 1、在登录的时候在服务器上注册自己 2、每次调用wcf服务的时候进行身份验证并且更新最后在线时间 3、控制最大在线用户数量 4、限制一号多开
software_artisan 2015-04-30
  • 打赏
  • 举报
回复
OnlineManage类:
    public class OnlineManage
    {

        /// <summary>
        /// 用户会话列表
        /// </summary>
        public static List<Session> Sessions { get; set; }

        /// <summary>
        /// 最大在线用户数
        /// </summary>
        public static int MaxAuthorized { get; set; }

        /// <summary>
        /// 构造方法
        /// </summary>
        public OnlineManage()
        {
            Sessions = new List<Session>();
            MaxAuthorized = Convert.ToInt32(ConfigurationManager.AppSettings["MaxAuthorized"]);
        }

        /// <summary>
        /// 会话合法性验证
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static bool Verification(Session obj)
        {
            if (obj == null) return false;

            var us = Sessions.Find(s => s.UserId == obj.UserId);
            if (us != null && us.Signature == obj.Signature)
            {
                us.LastConnect = DateTime.Now;
                return true;
            }
            else
            {
                return false;
            }
        }

    }
Session类:
    public class Session
    {

        /// <summary>
        /// 会话ID
        /// </summary>
        public Guid SessionId { get; set; }

        /// <summary>
        /// 登录用户ID
        /// </summary>
        public Guid UserId { get; set; }

        /// <summary>
        /// 登录部门ID
        /// </summary>
        public Guid? DeptId { get; set; }

        /// <summary>
        /// 用户账号
        /// </summary>
        public string LoginName { get; set; }

        /// <summary>
        /// 登录用户名
        /// </summary>
        public string UserName { get; set; }

        /// <summary>
        /// 登录部门全称
        /// </summary>
        public string DeptName { get; set; }

        /// <summary>
        /// WCF服务基地址
        /// </summary>
        public string BaseAddress { get; set; }

        /// <summary>
        /// 用户签名
        /// </summary>
        public string Signature { get; set; }

        /// <summary>
        /// 用户机器码
        /// </summary>
        public string MachineId { get; set; }

        /// <summary>
        /// 上次连接时间
        /// </summary>
        public DateTime LastConnect { get; set; }

        /// <summary>
        /// 用户登录状态
        /// </summary>
        public LoginResult LoginStatus { get; set; }

    }

    public enum LoginResult
    {
        Success,
        Failure,
        Online,
        Banned,
        NotExist,
        Unauthorized
    }
服务端Login方法
        public Session UserLogin(Session obj)
        {
            if (obj == null) return null;

            if (OnlineManage.Sessions.Count >= OnlineManage.MaxAuthorized)
            {
                obj.LoginStatus = LoginResult.Unauthorized;
                return obj;
            }

            var user = CommonDAL.GetUser(obj.LoginName);
            if (user == null)
            {
                obj.LoginStatus = LoginResult.NotExist;
                return obj;
            }

            var us = OnlineManage.Sessions.Find(s => s.UserId == user.ID);
            if (user.Password.ToUpper() != obj.Signature)
            {
                obj.LoginStatus = LoginResult.Failure;
            }
            else if (!user.Validity)
            {
                obj.LoginStatus = LoginResult.Banned;
            }
            else
            {
                obj.UserId = user.ID;
                obj.UserName = user.Name;
                obj.LastConnect = DateTime.Now;
                if (us != null && us.MachineId != obj.MachineId)
                {
                    obj.LoginStatus = LoginResult.Online;
                }
                else
                {
                    obj.LoginStatus = LoginResult.Success;
                    OnlineManage.Sessions.Add(obj);
                    OnlineManage.Sessions.Remove(us);
                }
            }
            return obj;
        }
客户端longin方法:
        private void btnLogin_Click(object sender, EventArgs e)
        {
            Session.LoginName = txtUserName.Text.Trim();
            if (string.IsNullOrEmpty(Session.LoginName))
            {
                General.ShowMessage("请输入用户名!");
                txtUserName.Focus();
                return;
            }

            if (String.IsNullOrEmpty(txtPassWord.Text))
            {
                General.ShowWarning("密码不能为空!");
                txtPassWord.Focus();
                return;
            }

            Session.Signature = General.GetHash(txtPassWord.Text.Trim());
            Session.DeptId = (Guid?)lokDepartment.EditValue;
            Session.DeptName = lokDepartment.EditValue == null ? null : lokDepartment.Text;
            using (var cli = new LoginClient(Binding, _Address))
            {
                Session = cli.UserLogin(Session);
            }

            switch (Session.LoginStatus)
            {
                case LoginResult.Success:
                    panel.Visible = false;
                    ShowProgress("正在加载主窗体,请稍候…");

                    Config.SaveUserName(Session.LoginName);
                    DialogResult = DialogResult.OK;
                    break;

                case LoginResult.Failure:
                    General.ShowWarning("对不起,您输入的密码不正确!\r\n如果您不知道或遗忘自己的密码,请联系管理员。");
                    txtPassWord.EditValue = null;
                    txtPassWord.Focus();
                    break;

                case LoginResult.Online:
                    General.ShowWarning("对不起,当前用户已登录!\r\n如果您已经退出系统,请稍后再试。");
                    break;

                case LoginResult.NotExist:
                    General.ShowWarning("该账户不存在!请检查输入的用户名。\r\n如果您不知道自己的用户名,请联系管理员。");
                    txtUserName.EditValue = null;
                    txtUserName.Focus();
                    break;

                case LoginResult.Banned:
                    General.ShowWarning("该账户已封禁!在解封前您不能登录系统。\r\n如果您需要使用该账号登录系统,请联系管理员。");
                    break;

                case LoginResult.Unauthorized:
                    General.ShowWarning("在线用户数已达上限!您缺少足够的授权数量。\r\n请联系开发商购买足够的用户授权数量。");
                    break;
            }
        }
  • 打赏
  • 举报
回复
session模式不是asp.net里面的session……
  • 打赏
  • 举报
回复
session模式不是asp.net里面的session……
  • 打赏
  • 举报
回复
不能遍历。你需要自己重新设计所谓的“在线”机制。

110,535

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧