背景

OA管理系统中,员工提交申请单,消息实时通知到相关人员及时进行审批,审批之后将结果推送给用户。

技术选择

最开始发现的是firebase,于是很兴奋的开始倒腾起来。firebase用 起来倒是简单:引用一个js即可,按官网上的教程很快便应用到了项目中。第二天打开项目发现推送功能不好使了,这是为何?最后发现firebase官网打 不开了。。。难道firebase被google收了也会被天朝给墙掉?也许是firebase自己挂掉了,总之是用不了了。因为要完全把推送数据存放在 firebase服务器上来实现推送功能,就会有以下几个需要担心的问题:

1.数据不安全

2.对firebase依赖性太强

3.firebase收费(免费版太弱)

于是果断放弃firebase,朋友推荐有个叫SignalR的东东可以试试,这是专门为ASP.NET开发人员准备的一款消息推送类库,且不依赖别的服务器、免费。

使用方法

1.在nuget中搜索并添加SignalR最新版本

AngularJS+ASP.NET MVC+SignalR实现消息推送

2.在页面中引用jquery.signalR-2.2.0.min.js文件(依赖jquery),再添加<script src="/signalr/hubs"></script>用于自动生成signalr的脚本

3.添加MsgHub.cs类,用于处理对应用户信息和消息推送实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Microsoft.AspNet.SignalR;
using Microsoft.AspNet.SignalR.Hubs;
 
namespace ZmeiOA.Services
{
         [Authorize]
    [HubName("ZmHub")]
    public class MsgHub : Hub
    {/// <summary>
        /// 连接
        /// </summary>
        /// <returns></returns>
        public override System.Threading.Tasks.Task OnConnected()
        {
            Groups.Add(Context.ConnectionId, Context.User.Identity.Name);
            return base.OnConnected();
        }
 
        /// <summary>
        /// 重新连接
        /// </summary>
        /// <returns></returns>
        public override System.Threading.Tasks.Task OnReconnected()
        {
            Groups.Add(Context.ConnectionId, Context.User.Identity.Name);
            return base.OnReconnected();
        }
 
        /// <summary>
        /// 断开连接
        /// </summary>
        /// <param name="stopCalled"></param>
        /// <returns></returns>
        public override System.Threading.Tasks.Task OnDisconnected(bool stopCalled)
        {
            Groups.Remove(Context.ConnectionId, Context.User.Identity.Name);
            return base.OnDisconnected(stopCalled);
        }
    }
}

 

说明:SignalR的推送消息是基于用户连接(ConnectionId)的,SignalR会为每个会话自动生成一个 ConnectionId。但是我们的推送是基于用户的(权限体系),也就是只有登录之后才注册到此Hub。在这里我用到的是SignalR中的 Groups,把登录用户的ConnectionId与对应的UserId添加到Groups中,推送的时候只要指定Groups的 Name,SignalR便会自动找出其对应的ConnectionId并发送消息(这种方式可能不是最好的,因为每个用户的UserId都会作为 Groups的Key添加进去,当用户量很大的时候Groups也会很庞大,但我还没找到更好的替代方案)。

4.消息推送有两种形式:a.服务端直接推送;b.客户端推送。

区别在于,服务端推送是在持久化数据之后便可以直接把消息推送给相关人;而客户端推送是持久化数据之后,客户端根据返回值的情况,使用 SignalR的JS方法调用服务端的推送功能。我使用的是服务器端直接推送数据,因为在持久化数据之后就完全可以根据业务通知相关人,如果返回到前台之 后再调用服务端的推送方法只是多此一举。

如:保存申请单成功之后立刻通知审批人

在Service中获取Hub的上下文

1
2
3
4
        /// <summary>
        /// 消息推送上下文
        /// </summary>
        protected static IHubContext ZmHubContext = GlobalHost.ConnectionManager.GetHubContext<MsgHub>();

 

在保存申请单之后给相关人员推送消息(注意:dynamic方法broadcastTodo就是在客户端需要接收消息的方法)

1
2
3
4
5
6
7
8
public static ApplyForm Save(FormView view)
{        
         //省略业务操作...
         //...
    //通知待办事项
    ZmHubContext.Clients.Groups(app.AuditorIds.Split(',')).broadcastTodo(app.AuditorIds, new { type = "new", data = app });
    return app;
}


5.在注册Angular模块时连接Hub并作为value传入到模块中,这样每个controller都可以使用此连接:

1
2
3
        var zmHub = $.connection.ZmHub;
 
        var zmApp = angular.module('zmApp', ['ngRoute', 'ngResource', 'ngSanitize', 'ngMessages', 'ngSVGAttributes']).value('zmHub', zmHub);

 

  6.在首页的controller中接收推送的消息,并提供两种推送体验:a.桌面通知;b.页面内消息。桌面通知很酷,即使是浏览器最小化的时候,在桌面右下角也可以收到提示(Chrome和Firefox支持,IE不支持)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
zmHub.client.broadcastTodo = function (userIds, obj) {
    //通知下级控制器有待办事项
    $scope.$broadcast('todoschanged', obj);
    //显示桌面通知
    if (obj.type == 'new') {
                 //桌面通知标题
        var title = '来自[' + obj.data.ApplicantName + ']的申请单';
        //申请单类型名称
        var formTypeName = DefaultService.getEnumText(17, obj.data.Type);
        var msg = '[' + formTypeName + ']' + obj.data.Name;
                 //桌面通知方法
        NotifyService.Notify('todos', title, msg);
    }
}


 

下级控制器的接收方法(关于angularjs的broadcast不多解释,不明白的可以到官网查阅):

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//接收推送的待办事项
$scope.$on('todoschanged', function (d, obj) {
    $scope.$apply(function () {
                 //如果是新增数据,在当前列表中添加一条
        if (obj.type == 'new') {
            $scope.todoApps.unshift(obj.data);
        }
        else if (obj.type == 'delete') {//如果是撤销申请,则把当前列表中那条数据删除
            for (var j = 0; j < $scope.todoApps.length; j++) {
                if ($scope.todoApps[j].Id == obj.data.Id) {
                    $scope.todoApps.splice(j, 1);
                    break;
                }
            }
        }
    });
});

桌面通知服务:

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
//桌面通知服务
zmApp.factory('NotifyService', function () {
 
    return {
        Notify: function (icon, title, msg) {
            // At first, let's check if we have permission for notification
            // If not, let's ask for it
            if (window.Notification && Notification.permission !== "granted") {
                Notification.requestPermission(function (status) {
                    if (Notification.permission !== status) {
                        Notification.permission = status;
                    }
                });
            }
            var iconPath = '/Content/images/icons/' + (icon || 'info') + '.png';
            var options = {
                lang: 'zh-CN',
                body: msg,
                icon: iconPath
            };
            var notify;
            // If the user agreed to get notified
            if (window.Notification && Notification.permission === "granted") {
                notify = new Notification(title, options);
            }
            else if (window.Notification && Notification.permission !== "denied") {
                Notification.requestPermission(function (status) {
                    if (Notification.permission !== status) {
                        Notification.permission = status;
                    }
                    if (status === "granted") {
                        notify = new Notification(title, options);
                    }
                    else {
                        console.log('您禁止了桌面通知,无法推送到您的桌面!');
                    }
                });
            }
            else {
                console.log('您禁止了桌面通知,无法推送到您的桌面!');
            }
            if (notify) {
                notify.onclose = function (evt) {
 
                };
                //点击切换到浏览器
                notify.onclick = function () {
                    window.focus();
                };
            }
        }
    };
});

桌面通知效果:

AngularJS+ASP.NET MVC+SignalR实现消息推送

 

总结:

用SignalR推送消息总的来说比较简单,只需要简单几步便可实现,而且是selfhost,不必担心对其它服务器的依赖和数据安全问题,感兴趣的朋友可以试试

来自:http://www.cnblogs.com/usea/p/4282560.html

posted @ 2017-02-21 14:51 90后梦想大师 阅读(747) 评论(0) 推荐(0) 编辑
摘要: ajax实现长连接 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8" isELIgnored="false" %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Trans 阅读全文
posted @ 2017-02-20 16:52 90后梦想大师 阅读(516) 评论(0) 推荐(2) 编辑
摘要: 原文地址:http://blog.csdn.net/vbirdbest/article/details/51122637 使用场景: 假如你的项目(这里指的是手机客户端项目)的某个版本(例如1.0版本)已经完成开发、测试并已经上线了,接下来接到新的需求,新需求的开发需要修改多个文件中的代码,当需求已 阅读全文
posted @ 2017-05-10 15:16 90后梦想大师 阅读(405) 评论(0) 推荐(0) 编辑
摘要: 新建资源仓库时,可选择默认创建三个文件夹。这三个文件夹分别是【trunk】【branches】【tags】 【Trunk】 一般用于存放目前项目主线,也就是项目所有功能模块的集合体,一整个项目所有代码库。一般来说,存放在trunk中的代码都是稳定可正常运行的。 【Branches】 分支,其实也就是 阅读全文
posted @ 2017-05-10 14:15 90后梦想大师 阅读(6237) 评论(0) 推荐(0) 编辑
摘要: 将已有项目代码加入svn版本控制 - TortoiseSVN入门篇Windows下SVN实用教程(以TortoiseSVN作为客户端(client)) 翻译: Bravo Young Next: 版本库的备份与存储 目录 导引 安装Subversion 安装TortoiseSVN 一步步地操作 步骤 阅读全文
posted @ 2017-05-10 14:13 90后梦想大师 阅读(1437) 评论(0) 推荐(0) 编辑
摘要: 交换机(Switch)意为“开关”是一种用于电(光)信号转发的网络设备。它可以为接入交换机的任意两个网络节点提供独享的电信号通路。最常见的交换机是以太网交换机。其他常见的还有电话语音交换机、光纤交换机等。 定义 交换机 交换(switching)是按照通信两端传输信息的需要,用人工或设备自动完成的方 阅读全文
posted @ 2017-05-10 10:21 90后梦想大师 阅读(3035) 评论(0) 推荐(1) 编辑
摘要: ESXi专为运行虚拟机、最大限度降低配置要求和简化部署而设计。只需几分钟时间,客户便可完成从安装到运行虚拟机的全过程,特别是在下载并安装预配置虚拟设备的时候。 在VMware Virtual Appliance Marketplace 上有800多款为VMware hypervisor 创建的虚拟设 阅读全文
posted @ 2017-05-10 10:09 90后梦想大师 阅读(867) 评论(0) 推荐(0) 编辑
摘要: VMware vSphere集成容器(VIC)建立了一个在轻量级虚拟机内部署并管理容器的环境。全新的虚拟机环境提供了更高级别的硬件隔离度,灵活性以及可扩展性使得容器对开发人员以及企业应用具有如此大的吸引力。 构建家庭vSphere实验环境编辑 为了跟进vSphere最新变化和新功能,有许多设备可以用 阅读全文
posted @ 2017-05-10 10:04 90后梦想大师 阅读(1169) 评论(0) 推荐(0) 编辑
摘要: 虚拟机(Virtual Machine)指通过软件模拟的具有完整硬件系统功能的、运行在一个完全隔离环境中的完整计算机系统。 虚拟系统通过生成现有操作系统的全新虚拟镜像,它具有真实windows系统完全一样的功能,进入虚拟系统后,所有操作都是在这个全新的独立的虚拟系统里面进行,可以独立安装运行软件,保 阅读全文
posted @ 2017-05-10 10:00 90后梦想大师 阅读(745) 评论(0) 推荐(0) 编辑
摘要: 进入vi的命令 vi filename :打开或新建文件,并将光标置于第一行首 vi +n filename :打开文件,并将光标置于第n行首 vi + filename :打开文件,并将光标置于最后一行首 vi +/pattern filename:打开文件,并将光标置于第一个与pattern匹配 阅读全文
posted @ 2017-05-09 17:27 90后梦想大师 阅读(220) 评论(0) 推荐(0) 编辑
摘要: “高可用性”(High Availability)通常来描述一个系统经过专门的设计,从而减少停工时间,而保持其服务的高度可用性。 计算机的高可用性 计算机系统的可用性用平均无故障时间(MTTF)来度量,即计算机系统平均能够正常运行多长时间,才发生一次故障。系统的可用性越高,平均无故障时间越长。可维护 阅读全文
posted @ 2017-05-09 16:13 90后梦想大师 阅读(497) 评论(0) 推荐(0) 编辑
摘要: 很多时候,经验是被痛苦逼出来的,流程是被错误逼出来的。在上线的过程当中,这段时间遇到了一些问题,造成了研发耽误了不少时间。原因是上线的不规范性以及没有任何的权限限制。 另外互联网项目版本开发都非常频繁。一天上线十几个小版本,也是有可能的。像我现在的公司,经常一天修改好多次文案,就需要不断的上线。如果 阅读全文
posted @ 2017-05-09 16:07 90后梦想大师 阅读(645) 评论(0) 推荐(0) 编辑
摘要: 之前的上线流程很简单粗暴如图: 这简直是灾难性质的,上传 SVN,在测试服务器上看看正在调试的接口没问题,直接 sync 到线上服务器。代码无法回滚,只能覆盖。而客户端的同学需要稳当的 api 作为调试,最初的做法,他们需要新数据,我们就需要上线代码。这很坑爹,也许某人某段代码正写了一半,又正好提交 阅读全文
posted @ 2017-05-09 16:03 90后梦想大师 阅读(2422) 评论(0) 推荐(0) 编辑
摘要: 网络是什么? 网络是什么呢?简单的说,只要是两部以上的计算机,透过网络线或者是其它的网络媒体(例如无线网卡、专线、Cable缆线等等)连接在一起,以进行档案传输、讯息传递等等功能,那就形成一个『网络世界』啦!那么网络有没有大小之分呢?基本上,如果您的网络是在您的研究室内几部计算机,或者是大楼内的所有 阅读全文
posted @ 2017-05-09 15:05 90后梦想大师 阅读(1943) 评论(0) 推荐(1) 编辑
摘要: Linux目录结构及文件基本操作 1.Linux的文件组织目录结构(遵循FHS标准) FHS(Filesystem Hierarchy Standard)标准:多数Linux版本采用这种文件组织形式,FHS定义了系统中每个区域的用途,所需要的最小构成的文件和目录同时还给出了例外处理与矛盾处理。 FH 阅读全文
posted @ 2017-05-09 14:56 90后梦想大师 阅读(317) 评论(0) 推荐(0) 编辑
摘要: 基本echo "hello word" 输出 hello wordtouch file 创建文件名为file 常用快捷键TAB:在忘记命令时,可以用来补全命令Ctrl+c:强制终止当前的程序Ctrl+d:键盘输入结束或者退出终端Ctrl+s:暂停当前程序,暂停后按下任意键恢复运行Ctrl+z:将当前 阅读全文
posted @ 2017-05-09 12:33 90后梦想大师 阅读(220) 评论(0) 推荐(0) 编辑
摘要: Linux是一套免费使用和自由传播的类Unix操作系统,是一个基于POSIX和UNIX的多用户、多任务、支持多线程和多CPU的操作系统。它能运行主要的UNIX工具软件、应用程序和网络协议。它支持32位和64位硬件。Linux继承了Unix以网络为核心的设计思想,是一个性能稳定的多用户网络操作系统。 阅读全文
posted @ 2017-05-09 11:19 90后梦想大师 阅读(391) 评论(0) 推荐(0) 编辑
摘要: ORACLE SQL语句共享 Oracle SQL语句具备共享特性,为了不让ORACLE数据库重复解析相同的简单单表SQL语句,ORACLE在SGA系统共享区域内SBP共享池内存放的SQL语句将被所有用户共享。(注:只适合单表查询,多表连接查询无效!) ORACLE SQL语句共享,表现在三个方面1 阅读全文
posted @ 2017-05-09 10:10 90后梦想大师 阅读(679) 评论(0) 推荐(0) 编辑
摘要: 引言 有时候有很多问题只有在线上或者预发环境才能发现,而线上又不能Debug,所以线上问题定位就只能看日志,系统状态和Dump线程,本文只是简单的介绍一些常用的工具,帮助定位线上问题。 问题定位 1: 首先使用TOP命令查看每个进程的情况,显示如下: 2: 再使用Top的交互命令数字1查看每个CPU 阅读全文
posted @ 2017-05-09 10:07 90后梦想大师 阅读(271) 评论(0) 推荐(0) 编辑
摘要: 搭建SVN服务,有效的管理代码,以下三步可以快速搞定。 1、安装 #yum install subversion 判断是否安装成功 #subversion -v svnserve, version 1.6.11 (r934486) 出现上面的提示,说明安装成功。 有了SVN软件后还需要建立SVN库。 阅读全文
posted @ 2017-05-09 10:06 90后梦想大师 阅读(149) 评论(0) 推荐(0) 编辑
摘要: 负载均衡建立在现有网络结构之上,它提供了一种廉价有效透明的方法扩展网络设备和服务器的带宽、增加吞吐量、加强网络数据处理能力、提高网络的灵活性和可用性。 一、HTTP重定向 当用户发来请求的时候,Web服务器通过修改HTTP响应头中的Location标记来返回一个新的url,然后浏览器再继续请求这个新 阅读全文
posted @ 2017-05-09 10:04 90后梦想大师 阅读(362) 评论(0) 推荐(0) 编辑
摘要: HAProxy提供高可用性、负载均衡以及基于TCP和HTTP应用的代理,支持虚拟主机,它是免费、快速并且可靠的一种解决方案。HAProxy特别适用于那些负载特大的web站点,这些站点通常又需要会话保持或七层处理。HAProxy运行在当前的硬件上,完全可以支持数以万计的并发连接。并且它的运行模式使得它 阅读全文
posted @ 2017-05-09 10:00 90后梦想大师 阅读(274) 评论(0) 推荐(0) 编辑
摘要: HAProxy是一个使用C语言编写的自由及开放源代码软件,其提供高可用性、负载均衡,以及基于TCP和HTTP的应用程序代理。 HAProxy特别适用于那些负载特大的web站点,这些站点通常又需要会话保持或七层处理。HAProxy运行在当前的硬件上,完全可以支持数以万计的并发连接。并且它的运行模式使得 阅读全文
posted @ 2017-05-09 09:58 90后梦想大师 阅读(123) 评论(0) 推荐(0) 编辑
摘要: mpls vpn MPLS-VPN是指采用MPLS(多协议标记转换)技术在骨干的宽带IP网络上构建企业IP专网,实现跨地域、安全、高速、可靠的数据、语音、图像多业务通信,并结合差别服务、流量工程等相关技术,将公众网可靠的性能、良好的扩展性、丰富的功能与专用网的安全 、灵活、高效结合在一起。 中文名多 阅读全文
posted @ 2017-05-09 09:54 90后梦想大师 阅读(62) 评论(0) 推荐(0) 编辑
摘要: HA是双机接口,即说明这款防火墙支持双机冗余并行运行模式,可以用同型号的两台机器同时接上联和下联线路,并用线路将两台机器的HA口连接起来,达到协同工作,并行运行的功能。 高可用性H.A.(High Availability)指的是通过尽量缩短因日常维护操作(计划)和突发的系统崩溃(非计划)所导致的停 阅读全文
posted @ 2017-05-09 09:46 90后梦想大师 阅读(3300) 评论(0) 推荐(0) 编辑
摘要: 以下内容来自百度百科 简介 数据中心不仅是一个网络概念,还是一个服务概念,它构成了网络基础资源的一部分,提供了一种高端的数据传输服务和高速接入服务。数据中心提供给用户综合全面的解决方案,为政府上网、企业上网、企业IT管理提供专业服务,使得企业和个人能够迅速借助网络开展业务,把精力集中在其核心业务策划 阅读全文
posted @ 2017-05-09 09:38 90后梦想大师 阅读(1379) 评论(0) 推荐(0) 编辑
该文被密码保护。 阅读全文
posted @ 2017-05-08 14:25 90后梦想大师 阅读(1) 评论(0) 推荐(0) 编辑
该文被密码保护。 阅读全文
posted @ 2017-05-08 14:24 90后梦想大师 阅读(0) 评论(0) 推荐(0) 编辑
该文被密码保护。 阅读全文
posted @ 2017-05-08 14:07 90后梦想大师 阅读(1) 评论(0) 推荐(0) 编辑
该文被密码保护。 阅读全文
posted @ 2017-05-08 13:52 90后梦想大师 阅读(0) 评论(0) 推荐(0) 编辑
该文被密码保护。 阅读全文
posted @ 2017-05-08 13:44 90后梦想大师 阅读(1) 评论(0) 推荐(0) 编辑
摘要: FinalBuilder 使用这款自动化创建和发布管理工具,软件开发者可以定义和维护一个可靠的以及可重复创建的程序。FinalBuilder包括集成的带有版本的控制系统,文件和目录选项,重复器,源代码编译,测试工具,数据库系统,安装工具,以及用于在因特网上进行配置的行为和CD或者DVD刻录功能。该软 阅读全文
posted @ 2017-05-08 12:37 90后梦想大师 阅读(2722) 评论(0) 推荐(0) 编辑
摘要: FinalBuilder 使用这款自动化创建和发布管理工具,软件开发者可以定义和维护一个可靠的以及可重复创建的程序。FinalBuilder包括集成的带有版本的控制系统,文件和目录选项,重复器,源代码编译,测试工具,数据库系统,安装工具,以及用于在因特网上进行配置的行为和CD或者DVD刻录功能。该软 阅读全文
posted @ 2017-05-08 12:36 90后梦想大师 阅读(151) 评论(0) 推荐(0) 编辑
摘要: k2服务器即K2 WORKSPACE管理介绍: k2 管理平台统一管理基于K2开发的所有流程的跟踪调试以及基本配置信息。 具体完成的操作有以下几个部分: 1 配置K2环境相关属性。包括全局变量等 2 管理K2工作流服务器基本配置。包括服务器权限以及部署在服务器上所有流程的管理。 3 查看K2工作流当 阅读全文
posted @ 2017-05-08 12:32 90后梦想大师 阅读(1356) 评论(0) 推荐(1) 编辑
摘要: 上一篇讲到K2安装的具体操作,本篇我们具体讲一下在VS环境下如何开发K2工作流。 常用工具控件说明: 节点关联线:流程各节点之间的关联线 客户端节点:流程的基本元素 服务器端节点:流程的完成标识节点 节点详细配置: 从工具箱找到客户端节点拖动到开发主页面中如图示: 一 完成节点事件设置 1 设置 E 阅读全文
posted @ 2017-05-08 12:30 90后梦想大师 阅读(1812) 评论(0) 推荐(1) 编辑
摘要: K2介绍: K2是基于BPM的流程开发平台,它支持在net开发环境/visio/moss等不同环境下进行流程开发。 K2本身部署简单,操作灵活,非常适合大中型企业流程开发和部署。 K2安装步骤: 首先从图示中找到相关文件进行安装 1 我们需要先安装VisualStudio2005,其中要选择VS f 阅读全文
posted @ 2017-05-08 11:51 90后梦想大师 阅读(699) 评论(0) 推荐(1) 编辑
摘要: 1.移动端访问远程服务时,建议使用WebAPI 2.用不同浏览器访问WebAPI时返回的文本格式是不同的,Chrome Firefox将在浏览器中以XML形式显示此列表,IE浏览器将获得Json格式的数据,区别的原因在于不同浏览器的请求头不同,分别为:application/XML和applicat 阅读全文
posted @ 2017-03-20 15:28 90后梦想大师 阅读(1857) 评论(0) 推荐(0) 编辑
摘要: 一、首先,在MVC项目中安装SingalR包(SingalR2.0需要.net4.5以上,VS2010可以安装1.1.3版本,本例为VS2010+SignalR1.1.3)。 打开工具—NuGet程序管理器—程序包管理器控制台,输入: Install-Package Microsoft.AspNet 阅读全文
posted @ 2017-03-19 19:23 90后梦想大师 阅读(1476) 评论(0) 推荐(0) 编辑
摘要: 提起函数式编程,大家一定想到的是语法高度灵活和动态的LISP,Haskell这样古老的函数式语言,往近了说ruby,javascript,F#也是函数式编程的流行语言。然而自从.net支持了lambda表达式,C#虽然作为一种指令式程序设计语言,在函数式编程方面也毫不逊色。我们在使用c#编写代码的过 阅读全文
posted @ 2017-03-19 18:52 90后梦想大师 阅读(220) 评论(0) 推荐(0) 编辑
摘要: 一、理解SignalR ASP .NET SignalR 是一个ASP .NET 下的类库,可以在ASP .NET 的Web项目中实现实时通信(即:客户端(Web页面)和服务器端可以互相实时的通知消息及调用方法),SignalR有三种传输模式:LongLooping(长轮询)、WebSocket(H 阅读全文
posted @ 2017-03-18 14:53 90后梦想大师 阅读(712) 评论(0) 推荐(0) 编辑
摘要: JS部分 $.connection.hub.start().done(function () { alert(ok); }).fail(function (error) { alert(error); }); 建立连接, done 成功后的回掉函数,fail 失败后的回掉函数,基本所有的通讯操作(调 阅读全文
posted @ 2017-03-18 14:36 90后梦想大师 阅读(285) 评论(0) 推荐(0) 编辑
摘要: 开发了一个WindowsService消息服务器,刚开始一直都是在代码中把IP地址写死,所以每次只要是更换了新的IP地址后,都需要重新编译项目。所以考虑把ip配置到config文件中, 这样做的好处是,后期如果ip地址改变,不需要重新编译项目,只需要修改config中的配置文件就可以。具体的配置方法 阅读全文
posted @ 2017-03-15 09:23 90后梦想大师 阅读(1106) 评论(0) 推荐(1) 编辑
点击右上角即可分享
微信分享提示