今天看了下websocket的知识,了解到这是html5新增的特性,主要用于实时web的通信。之前客户端获取服务端的数据,是通过客户端发出请求,服务端进行响应的模式,或者通过ajax每隔一段时间从后台发出请求,然后更新页面的信息,这种轮询的方式使得用户感觉页面是“实时响应”的,这样做虽然简单但未免有些暴力,另外每次请求都会有TCP三次握手并且附带了http头信息,服务器表示压力很大,这就造成了性能上和延迟的问题。

后来的技术方案中又出现了长轮询、Comet、浏览器插件(flash)和Java等来实现服务器往客户端推送消息,但都有一些弊端。

WebSocket的出现,意味着另一种解决方案,其提供了基于TCP的双向的、全双工(发送数据的同时也能够接受数据,两者同步进行)的socket连接。使用websocket,一旦服务端和客户端之间完成握手,信息就可以随意往来两端,而不用附件那些无用的http头信息,降低了带宽的占用,提高了性能,降低了延时。但其缺陷是浏览器的支持不够,比如IE,到了IE10才支持。

现在就通过一个简单的例子来讲讲其运用过程,先上下效果图:

项目的环境:.NET 4.5 +MVC 4 +JQuery+HTML5+VS2013+IE11

核心的实现过程,分以下几步:

1、websocket的创建、发送消息、接受消息、关闭

2、服务端的响应

下面针对上面的步骤,具体讲解下:

1、websocket的创建、发送消息、接受消息、关闭

websocket里包含的几个重要事件如下图: onopen onmessage onerror onclose;

websocket的创建: 这时连接会发送到服务端后台代码,进行客户端和服务端的握手,如果握手成功,则会触发onopen事件,表示连接建立;如果连接失败,就会执行onerror事件,随后执行onclose事件。当客户端获取到服务端推送的消息后,就会执行onmessage事件。

    try{
if ("WebSocket" in window) { //判断浏览器是否支持WebSocket
socket = new WebSocket("ws://localhost:13458/Socket/SocketHandler.ashx"); //socket连接服务端地址
}
}
catch(ex)
{
log("您的浏览器不支持WebSocket,请切换到更高版本 或用chrome firefox");
return;
} //相应的socket事件
//socket建立连接
socket.onopen = function () {
//连接成功,将消息广播出去
isSocketConnect = true;
$("#btnWs").val("断开");
sendSocketMessage(Event,"进入聊天室");
}
//socket得到服务端广播的消息
socket.onmessage = function (event) {
Log(event.data);
}
//socket连接关闭
socket.onclose = function () {
Log("socket closed!");
}
//socket连接出现错误
socket.onerror = function (event) {
Log("socket connect error");
}

当然客户端也可以往服务端发送消息,发送事件便是socket.send(data);data代表发送给服务端的数据:具体代码如下

if (socket.readyState == WebSocket.OPEN) {
if ($("#txtMsg").val() == "") {
if (!msg) {
return; //空文本不发送消息
}
}
//如果未输入用户名,根据当前时间生成游客昵称
if ($("#userName").val() == "") {
var d = new Date();
$("#userName").val("游客" + d.getMinutes() + "_" + d.getSeconds() + "_" + d.getMilliseconds());
}
if (!msg) {
msg = "" + $("#userName").val() + ":" + "<div class='divChat'>" + $("#txtMsg").val() + "</div>";
}
else {
msg = "" + $("#userName").val() + " " + msg;
}
socket.send(msg);
$("#txtMsg").val(""); //清空已输入的数据
$("#txtMsg").focus();
}

2、服务端的响应

这里我们添加一般处理程序来进行响应和推送客户端消息,其中有一点要处理的是 我们要实现即时多人聊天,就要把客户端发过来的消息广播到其他客户端,这里实现原理也很简单,就是把所有的连接用list存起来,然后遍历list集合,将消息发送给各个客户端。具体实现代码如下:

    public class SocketHandler : IHttpHandler
{
//用来存储当前所有连接的客户单
public static List<WebSocket> WebSocketList;
public void ProcessRequest(HttpContext context)
{
if (WebSocketList == null)
{
WebSocketList = new List<WebSocket>();
}
HttpContext.Current.AcceptWebSocketRequest(async (contexts) =>
{
WebSocket socket = contexts.WebSocket;
while (true)
{
ArraySegment<byte> buffer = new ArraySegment<byte>(new byte[1024]);
CancellationToken token;
WebSocketReceiveResult result = await socket.ReceiveAsync(buffer, token);
//获取客户端发过来的消息
string clientMessage = Encoding.UTF8.GetString(buffer.Array, 0, result.Count); if (socket.State == WebSocketState.Open)
{
//重新组织消息,发送给客户端
clientMessage = DateTime.Now.ToString() + " " + clientMessage;
buffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes(clientMessage));
//如果该客户端为初次加入,添加到用户列表;
if (!WebSocketList.Contains(socket))
{
WebSocketList.Add(socket);
}
//将消息进行广播
foreach (WebSocket item in WebSocketList)
{
await item.SendAsync(buffer, WebSocketMessageType.Text, true, CancellationToken.None);
}
}
if (socket.State == WebSocketState.CloseReceived)
{
//客户断开的时候,要从列表中移除
WebSocketList.Remove(socket);
}
}
});
}

参考资料:使用 HTML5 WebSocket 构建实时 Web 应用

源码下载

ps:离职了,找工作中……广州 围观简历

喜欢就动动手指支持下!您的支持是我最大动力!

C++之Effective STL学习笔记Item21

 

好了,先贴一段英文,真心不想翻译过来,而且感觉也翻译不到那么到位:

The STL is awash in comparisons of objects to see if they have the same value. For example, when you ask find to locate the first object in a range with a particular value, find has to be able to compare two objects to see if the value of one is the same as the value of the other. Similarly, when you attempt to insert a new element into a set, set::insert has to be able to determine whether that element’s value is already in the set.

The find algorithm and set’s insert member function are representative of many functions that must determine whether two values are the same. Yet they do it in different ways. find’s definition of “the same” is equality, which is based on operator==. set::insert’s definition of “the same” is equivalence, which is usually based on operator<.

Operationally, the notion of equality is based on operator==. If the expression “x == y” returns true, x and y have equal values, otherwise they don’t.

x and y have equivalent values with respect to operator< if the following expression is true:

!(x < y) && !(y < x)

好了,关于等价和等值的讨论,我们先到此为止。我们引入下一话题,假设我们现在创建如下一个set:

set<int, less_equal<int> > s; // s is sorted by “<=”

向其中插入10:

s.insert(10);

然后再向其插入10,我们知道,set中的元素是没有重复的,所以程序会判断10是否已经在当前set中,为了方便说明,我们把第一个插入的10称为10A,第二个称为10B。set的判断过程会是10A和10B是否是一样的,set所定义的一样就是我们之前提到的equivalence

那么程序中的less_equal是怎么来判断的呢?我们根据上面的推导,一个合理的推导,set可能是这样来判断的:

!(10A <= 10B) && !(10B <= 10A)      // test 10A and 10B for equivalence

当然上头的判定的结果为:!(true) && !(true) ,等价于 false && false,所以最终的结果会是false,也就是说,判定结果告诉我们,10A和10B is not equivalent!然后10B,也就是10会被再一次插入到set中,oh, no!

好了,这只是个玩笑,set可不会弱到如此地步,set中是不会存在重复元素的。小伙伴们肯定觉得疑惑了,这说了半天有毛用啊,set又不会使用less_equal这样的顺序,因为压根就不允许equal的情况发生,你这不是找别扭呢嘛!

别急,set有不重复这个特性,那么要是是个multiset呢,按照这个思路,这样的操作一定会成功,会认为是两个不同的元素插入到multiset内部,假设我们在后面需要做equal_range的相关操作(it identifies a range of equivalent values),问题就大了!

哈哈,和大家开了个很大的玩笑,STL是经过千锤百炼的,怎么可能存在这样傻的问题!关于这个问题SGI是最权威的了,我们可以去SGI查查,看到底是怎么回事!还真有,关键字:Strict Weak Ordering,好了让我们看看是怎么解决这个问题的:

明白了吧,人家是避免<=这样的比较出现,怎样避免?我目前认为避免的意思就是不能这样,这样就不行,看代码吧:

multiset<int, less_equal<int> > s;
s.insert(10);
s.insert(10);

这段代码编译通过,但是执行时会报assert错误!我没有搞清楚其中的原理,继续研究吧!

好了,绕了这么一大圈,其实就是想告诉你,在实现自己的类似less_equal仿函数的时候,一定要留神了,千万不要存在这样的bug!

感谢大家的阅读,希望能帮到大家!

Published by Windows Live Writer.

作者: 薛定谔の喵 
出处: http://www.cnblogs.com/berlin-sun/ 
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利。

 
 
标签: C++STLsetless_equal
 
分类: MVCHTML5

C++之Effective STL的更多相关文章

  1. 容器使用的12条军规——《Effective+STL中文版》试读

    容器使用的12条军规——<Effective+STL中文版>试读     还 记的自己早年在学校学习c++的时候,老师根本就没有讲STL,导致了自己后来跟人说 起会C++的时候总是被鄙视, ...

  2. Effective STL中文版 译序

    <Effective STL中文版>译序 就像本书的前两本姊妹作(Effective C++.More Effective C++)一样,本书的侧重点仍然在于提升读者的经验,只不过这次将焦 ...

  3. 《Effective STL中文版》前言

    <Effective STL中文版>前言     我第一次写关于STL(Standard Template Library,标准模板库)的介绍是在1995 年,当时我在More Effec ...

  4. Effective STL 中文版(大全)

    Effective STL 中文版(大全) 作者:winter 候捷说,对于STL,程序员有三个境界,开始是使用STL,然后是理解STL,最后是补充STL.Effective STL是一本非常好的书, ...

  5. [置顶] Effective STL 学习笔记

    看Effective STL 作的一些笔记,希望对各位有帮助. 以下是50条条款及相关解释. 容器 1. 慎重选择容器类型,根据需要选择高效的容器类型. 2. 不要试图编写独立于容器类型的代码. 3. ...

  6. Effective STL 读书笔记

    Effective STL 读书笔记 标签(空格分隔): 未分类 慎重选择容器类型 标准STL序列容器: vector.string.deque和list(双向列表). 标准STL管理容器: set. ...

  7. Effective STL读书笔记

    Effective STL 读书笔记 本篇文字用于总结在阅读<Effective STL>时的笔记心得,只记录书上描写的,但自己尚未熟练掌握的知识点,不记录通用.常识类的知识点. STL按 ...

  8. Effective STL 43: Prefer algorithm calls to hand-written loops

    Effective STL 43: Prefer algorithm calls to hand-written loops */--> div.org-src-container { font ...

  9. Effective STL 学习笔记 39 ~ 41

    Effective STL 学习笔记 39 ~ 41 */--> div.org-src-container { font-size: 85%; font-family: monospace; ...

随机推荐

  1. 从头开始学JavaScript (五)——操作符(二)

    原文:从头开始学JavaScript (五)--操作符(二) 一.乘性操作符 1.乘法:*      乘法操作符的一些特殊规则: 如果操作数都是数值,按照常规的乘法计算,如果乘积超过了ECMAscri ...

  2. C语言qsort函数算法性能测试

    对于该算法的复杂性.一个直接的方法是测量的一定量的算法级数据的执行时间的感知. 随着C语言提供qsort对于示例.随着100一万次的数据,以测试其计算量.感知O(nlg(n))时间成本: C码如下面: ...

  3. A generic error occurred in GDI+. 上传图片报错

    代码就不说了,因为本地测试 ok, 服务端 就不行 ,服务器 环境 阿里云 win2008 r2  64 位 原因 是我没有这是 文件加权限 : 左边 的 少了 权限~ 代码 :含义是 网络图片 裁剪 ...

  4. C语言双向链表

    原文:C语言双向链表 今天写了点双向链表的各种操作,写插入的时候费了点时间,不过,现在看来还是值得耗费那点时间去写的,这种小东西应该能信手拈来才行啊. /*双向链表*/ #include <st ...

  5. JS子元素oumouseover触发父元素onmouseout

    原文:JS子元素oumouseover触发父元素onmouseout JavaScript中,父元素包含子元素: 当父级设置onmouseover及onmouseout时,鼠标从父级移入子级,则触发父 ...

  6. ie6、ie7真的不支持inline-block吗?

    本来今天想出JavaScript继承的博文的,由于也才刚学习不久,以及工作比较忙,所以暂推两天写JavaScript的继承,喜欢的童鞋们关注我的博客哟! okay,言归正传.之前在接触前端的时候,处理 ...

  7. 萧墙HTML5手机发展之路(53)——jQueryMobile页面之间的参数传递

    基于单个页面模板HTTP通过路POST和GET请求传递参数.在多页模板,并且不需要server沟通,通常有三种方式在多页模板来实现页面之间的参数传递. 1.GET道路:上一页页生成参数并传递到下一个页 ...

  8. 全球最快的JS模板引擎:tppl

    废话不多说,先上测试: 亲测请访问:[在线测试地址]单次结果不一定准确,请多测几次. tppl 的编译渲染速度是著名的 jQuery 作者 John Resig 开发的 tmpl 的 43 倍!与第二 ...

  9. Java程序单元测试工具对比——Parasoft Jtest与Junit

    Web应用程序开发中,面向对象的Java语言占了不少的比重.对于Java应用程序的测试方法或方式多种多样,比较典型的是程序员自己来完成程序测试中的一个部分——单元测试. 之前,慧都资讯提到单元测试是程 ...

  10. [译]Java 设计模式之命令

    (文章翻译自Java Design Pattern: Command) 命令设计模式在进行执行和记录的时候需要一个操作及其参数和封装在一个对象里面.在下面的例子中,命令是一个操作,它的参数是一个Com ...