web服务端向客户发送提示信息

加密整理信息:
之前有一个网站需要向客户发送某些信息。构建了一点思路。


1、可以使用ajax定时请求:
让浏览器隔个几秒就发送一次请求,询问服务器是否有新信息。
或者:long poll 其实原理跟 ajax轮询 差不多,都是采用轮询的方式,不过采取的是阻塞模型(一直打电话,没收到就不挂电话),也就是说,客户端发起连接后,如果没消息,就一直不返回Response给客户端。直到有消息才返回,返回完之后,客户端再次建立连接,周而复始
这种有点像下面这种场景
客户端:啦啦啦,有没有新信息,没有的话就等有了才返回给我吧(Request)
服务端:额。。 等待到有消息的时候。。来 给你(Response)
客户端:啦啦啦,有没有新信息,没有的话就等有了才返回给我吧(Request) -loop
从上面可以看出其实这两种方式,都是在不断地建立HTTP连接,然后等待服务端处理,可以体现HTTP协议的另外一个特点,被动性。
何为被动性呢,其实就是,服务端不能主动联系客户端,只能有客户端发起。
简单地说就是,服务器是一个很懒的冰箱(这是个梗)(不会、不能主动发起连接),但是上司有命令,如果有客户来,不管多么累都要好好接待。
说完这个,我们再来说一说上面的缺陷(原谅我废话这么多吧OAQ)
从上面很容易看出来,不管怎么样,上面这两种都是非常消耗资源的。
ajax轮询 需要服务器有很快的处理速度和资源。(速度)long poll 需要有很高的并发,也就是说同时接待客户的能力。(场地大小)
所以 ajax轮询 和 long poll 都有可能发生这种情况。
客户端:啦啦啦啦,有新信息么?
服务端:月线正忙,请稍后再试(503 Server Unavailable)
客户端:。。。。好吧,啦啦啦,有新信息么?
服务端:月线正忙,请稍后再试(503 Server Unavailable)
客户端:然后服务端在一旁忙的要死:冰箱,我要更多的冰箱!更多。。更多。。(我错了。。这又是梗。。)
2、下面就到WebSockets了
先简单介绍下WebSockets:
通过上面这个例子,我们可以看出,这两种方式都不是最好的方式,需要很多资源。
一种需要更快的速度,一种需要更多的’电话’。这两种都会导致’电话’的需求越来越高。
哦对了,忘记说了HTTP还是一个状态协议。
通俗的说就是,服务器因为每天要接待太多客户了,是个健忘鬼,你一挂电话,他就把你的东西全忘光了,把你的东西全丢掉了。你第二次还得再告诉服务器一遍。
所以在这种情况下出现了,Websocket出现了。他解决了HTTP的这几个难题。首先,被动性,当服务器完成协议升级后(HTTP->Websocket),服务端就可以主动推送信息给客户端啦。所以上面的情景可以做如下修改。
客户端:啦啦啦,我要建立Websocket协议,需要的服务:chat,Websocket协议版本:17(HTTP Request)
服务端:ok,确认,已升级为Websocket协议(HTTP Protocols Switched)
客户端:麻烦你有信息的时候推送给我噢。。
服务端:ok,有的时候会告诉你的。
服务端:balabalabalabala
服务端:balabalabalabala
服务端:哈哈哈哈哈啊哈哈哈哈
服务端:笑死我了哈哈哈哈哈哈哈
就变成了这样,只需要经过一次HTTP请求,就可以做到源源不断的信息传送了。(在程序设计中,这种设计叫做回调,即:你有信息了再来通知我,而不是我傻乎乎的每次跑来问你 )
这样的协议解决了上面同步有延迟,而且还非常消耗资源的这种情况。那么为什么他会解决服务器上消耗资源的问题呢?
其实我们所用的程序是要经过两层代理的,即HTTP协议在Nginx等服务器的解析下,然后再传送给相应的Handler(PHP等)来处理。简单地说,我们有一个非常快速的 接线员(Nginx) ,他负责把问题转交给相应的 客服(Handler) 。
本身接线员基本上速度是足够的,但是每次都卡在客服(Handler)了,老有客服处理速度太慢。,导致客服不够。Websocket就解决了这样一个难题,建立后,可以直接跟接线员建立持久连接,有信息的时候客服想办法通知接线员,然后接线员在统一转交给客户。
这样就可以解决客服处理速度过慢的问题了。
同时,在传统的方式上,要不断的建立,关闭HTTP协议,由于HTTP是非状态性的,每次都要重新传输 identity info (鉴别信息),来告诉服务端你是谁。
虽然接线员很快速,但是每次都要听这么一堆,效率也会有所下降的,同时还得不断把这些信息转交给客服,不但浪费客服的处理时间,而且还会在网路传输中消耗过多的流量/时间。
但是Websocket只需要一次HTTP握手,所以说整个通讯过程是建立在一次连接/状态中,也就避免了HTTP的非状态性,服务端会一直知道你的信息,直到你关闭请求,这样就解决了接线员要反复解析HTTP协议,还要查看identity info的信息。
同时由客户主动询问,转换为服务器(推送)有信息的时候就发送(当然客户端还是等主动发送信息过来的。。),没有信息的时候就交给接线员(Nginx),不需要占用本身速度就慢的客服(Handler)了
3、好了现在实现一下(下面借鉴一下别人的demo,就不重写了哈)

ASP .NET SignalR 是一个ASP .NET 下的类库,可以在ASP .NET 的Web项目中实现实时通信。什么是实时通信的Web呢?就是让客户端(Web页面)和服务器端可以互相通知消息及调用方法,当然这是实时操作的。
WebSockets是 HTML5提供的新的API,可以在Web网页与服务器端间建立Socket连接,当WebSockets可用时(即浏览器支持Html5)SignalR使用WebSockets,当不支持时SignalR将使用其它技术来保证达到相同效果。
SignalR当然也提供了非常简单易用的高阶API,使服务器端可以单个或批量调用客户端上的JavaScript函数,并且非常 方便地进行连接管理,例如客户端连接到服务器端,或断开连接,客户端分组,以及客户端授权,使用SignalR都非常 容易实现。

一、首先,在MVC项目中安装SingalR包(SingalR2.0需要.net4.5以上,VS2010可以安装1.1.3版本,本例为VS2010+SignalR1.1.3)。

打开工具—NuGet程序管理器—程序包管理器控制台,输入:

Install-Package Microsoft.AspNet.SignalR-Version 1.1.3

安装完成后,一定要阅读弹出的txt,这里非常重要,

有两个很重要的提示,一是在Global.asax文件中加入RouteTable.Routes.MapHubs();二是在页面前端加入脚本<scriptsrc="~/signalr/hubs"></script>(注:本示例采用的是MVC4MVC其他版本有其他的写法,所以要读这个readme)。

二、安装完signalr包后,我们在项目中添加一个Home控制器以及它的ViewView选择母版页,记得在这个页面里加上

<scriptsrc="~/signalr/hubs"></script>

<script src="../../Scripts/jQuery.signalR-1.1.4.min.js"type="text/JavaScript"></script>

然后在项目中创建一个目录,目录里创建Hub类文件:

public class WorkflowHubHub

    {

        /// <summary>

        /// 静态用户列表

        /// </summary>

        private IList<string> userList = UserInfo.userList;

 

        /// <summary>

        /// 用户的connectionID与用户名对照表

        /// </summary>

        private readonly static Dictionary<stringstring>_connections = new Dictionary<stringstring>();

 

       /// <summary>

       /// 发送函数,前端触发该函数给服务器,服务器在将消息发送给前端,(Clients.All.(函数名)是全体广播,另外Clients提供了组播,广播排除,组播排除,指定用户播发等等)

       /// 该函数名在前端使用时一定要注意,前端调用该函数时,函数首字母一定要小写

       /// </summary>

       /// <param name="name1">发起者</param>

       /// <param name="name2">消息接收者</param>

        public voidSendByGroup(string name1, string name2)

        {

            //Client内为用户的id,是唯一的,SendMessage函数是前端函数,意思是服务器将该消息推送至前端

           Clients.Client(_connections[name2]).SendMessage("来自用户"+name1 + " " + DateTime.Now.ToString("yyyy/MM/ddhh:mm:ss")+"的消息推送!");

        }

 

        /// <summary>

        /// 用户上线函数

        /// </summary>

        /// <param name="name"></param>

        public voidSendLogin(string name)

        {

            if (!userList.Contains(name))

            {

               userList.Add(name);

               //这里便是将用户id和姓名联系起来

               _connections.Add(name, Context.ConnectionId); 

            }

            else

            {

               //每次登陆id会发生变化

               _connections[name] = Context.ConnectionId;

            }

            //新用户上线,服务器广播该用户名

           Clients.All.loginUser(userList);

        }

}

其中

public class UserInfo

    {

        public static IList<string>userList = new List<string>();

    }

为用户名称列表

 

HomeView中,Index.cshtml

<script src="../../Scripts/jquery.signalR-1.1.4.min.js"type="text/javascript"></script>

    <!--Reference the autogenerated SignalR hub script. 注意一定别忘记写这句,signalr生成的脚本都在这-->

    <script src="~/signalr/hubs"></script>

<h1>流程演示</h1>

<input type="hidden" id="displayname" />

<h2 id="thisname"></h2><br />

 

<select id="username" style="width:153px;">

</select>

<input id="send" type="button" value="发送" />

<div>

<h1 id="messgae"></h1>

</div>

<script type="text/javascript">

    $(function () {

 

       //前端Hub的使用,注意的是,Hub的名字是WorkflowHub,这里使用时首字母小写

        var work = $.connection.workflowHub;

 

        $('#displayname').val(prompt('请输入昵称:'''));

        $('#thisname').text('当前用户:'+$('#displayname').val());

 

        //对应后端的SendMessage函数,消息接收函数

       work.client.sendMessage = function(message) {

            $('#messgae').append(message + '</br>')

        };

 

        //后端SendLogin调用后,产生的loginUser回调

       work.client.loginUser = function(userlist) {

           reloadUser(userlist);

        };

 

        //hub连接开启

        $.connection.hub.start().done(function () {

 

            var username = $('#displayname').val();

 

            //发送上线信息

           work.server.sendLogin(username);

 

            //点击按钮,发送消息

            $('#send').click(function() {

               var friend = $('#username').val();

               //调用后端函数,发送指定消息

               work.server.sendByGroup(username, friend);

            });

 

        });

    });

 

    //重新加载用户列表

    var reloadUser = function(userlist) {

        $("#username").empty();

        for (i = 0;i < userlist.length; i++) {

            $("#username").append("<option value="+userlist[i]+">"+userlist[i]+"</option>");

        }

    }

</script>

调试执行,打开两个网页(如果提示signalr必须在jquery之后,就在_layout.cshtml中把jquery放前面),输入用户名称,登录后在列表中会显示当前登录的用户的信息:

另一个网页中输入李晨:

我们在李晨这里,给邓超发送,这样我们就会在邓超这里看到推送的消息了:

新增

SignalR跨域访问基于MVC4.5,SignalR2.2
客户端配置成服务端的地址:
   
 <script src="~/Scripts/jquery-1.10.2.min.js"></script>
    <script src="http://localhost:58690/Scripts/jquery.signalR-2.1.2.min.js" type="text/JavaScript"></script>
    <!--Reference the autogenerated SignalR hub script. -->
    <script src="http://localhost:58690/signalr/hubs"></script>
    <!--SignalR script to update the chat page and send messages.-->
    <script>
        $(function () {
            // Reference the auto-generated proxy for the hub.
            $.connection.hub.url = "http://localhost:58690/signalr/hubs";
            var chat = $.connection.chatHub;


服务端:startup进行增加跨域访问设置。
using Microsoft.Owin;
using Owin;
using Microsoft.Owin.Cors;//添加此引用


[assembly: OwinStartupAttribute(typeof(SignalRChat2.Startup))]
namespace SignalRChat2
{
    public partial class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            app.UseCors(CorsOptions.AllowAll);//跨域访问
            app.MapSignalR();
        }
    }
}

剩下的自行脑补吧,signalr刚刚接触,如果还看不懂可以去官网看看api


免费资源下载地址:http://download.csdn.net/detail/fuzhenglai/9865435

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MVC WebApi 用户权限验证及授权DEMO 前言:Web 用户的身份验证,及页面操作权限验证是B/S系统的基础功能,一个功能复杂的业务应用系统,通过角色授权来控制用户访问,本文通过Form认证,Mvc的Controller基类及Action的权限验证来实现Web系统登录,Mvc前端权限校验以及WebApi服务端的访问校验功能。 1 Web Form认证介绍 Web应用的访问方式因为是基于浏览器的Http地址请求,所以需要验证用户身份的合法性。目前常见的方式是Form认证,其处理逻辑描述如下: 1) 用户首先要在登录页面输入用户名和密码,然后登录系统,获取合法身份的票据,再执行后续业务处理操作; 2) 用户在没有登录的情况下提交Http页面访问请求,如果该页面不允许匿名访问,则直接跳转到登录页面; 3) 对于允许匿名访问的页面请求,系统不做权限验证,直接处理业务数据,并返回给前端; 4) 对于不同权限要求的页面Action操作,系统需要校验用户角色,计算权限列表,如果请求操作在权限列表中,则正常访问,如果不在权限列表中,则提示“未授权的访问操作”到异常处理页面。 2 WebApi 服务端Basic 方式验证 WebApi服务端接收访问请求,需要做安全验证处理,验证处理步骤如下: 1) 如果是合法的Http请求,在Http请求头中会有用户身份的票据信息,服务端会读取票据信息,并校验票据信息是否完整有效,如果满足校验要求,则进行业务数据的处理,并返回给请求发起方; 2) 如果没有票据信息,或者票据信息不是合法的,则返回“未授权的访问”异常消息给前端,由前端处理此异常。 3 登录及权限验证流程 1) 用户打开浏览器,并在地址栏中输入页面请求地址,提交; 2) 浏览器解析Http请求,发送Web服务器;Web服务器验证用户请求,首先判断是否有登录的票据信息; 3) 用户没有登录票据信息,则跳转到登录页面; 4) 用户输入用户名和密码信息; 5) 浏览器提交登录表单数据给Web服务器; 6) Web服务需要验证用户名和密码是否匹配,发送api请求给api服务器; 7) api用户账户服务根据用户名,读取存储在数据库中的用户资料,判断密码是否匹配; 7.1)如果用户名和密码不匹配,则提示密码错误等信息,然该用户重新填写登录资料; 7.2)如果验证通过,则保存用户票据信息; 8) 接第3步,如果用户有登录票据信息,则跳转到用户请求的页面; 9) 验证用户对当前要操作的页面或页面元素是否有权限操作,首先需要发起api服务请求,获取用户的权限数据; 10). api用户权限服务根据用户名,查找该用户的角色信息,并计算用户权限列表,封装为Json数据并返回; 11). 当用户有权限操作页面或页面元素时,跳转到页面,并由页面Controller提交业务数据处理请求到api服务器; 如果用户没有权限访问该页面或页面元素时,则显示“未授权的访问操作”,跳转到系统异常处理页面。 12). api业务服务处理业务逻辑,并将结果以Json 数据返回; 13). 返回渲染后的页面给浏览器前端,并呈现业务数据到页面; 14). 用户填写业务数据,或者查找业务数据; 15). 当填写或查找完业务数据后,用户提交表单数据; 16). 浏览器脚本提交get,post等请求给web服务器,由web服务器再次解析请求操作,重复步骤2的后续流程; 17). 当api服务器验证用户身份是,没有可信用户票据,系统提示“未授权的访问操作”,跳转到系统异常处理页面。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值