websockets学习笔记(一)

WebSocket是HTML5开始提供的一种浏览器与服务器间进行全双工通讯的网络技术。 WebSocket通信协议于2011年被IETF定为标准 RFC 6455,WebSocketAPI被W3C定为标准。

在WebSocket API中,浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。(维基百科)

背景

现在,很多网站为了实现推送技术,所用的技术都是轮询。 轮询是在特定的的时间间隔(如每1秒),由浏览器对服务器发出HTTP request,然后由服务器返回最新的数据给客户端的浏览器。这种传统的模式带来很明显的缺点,即浏览器需要不断的向服务器发出请求,然而HTTP request 的header是非常长的,里面包含的数据可能只是一个很小的值,这样会占用很多的带宽和服务器资源。

而比较新的技术去做轮询的效果是Comet,使用了AJAX。但这种技术虽然可达到双向通信,但依然需要发出请求,而且在Comet中,普遍采用了长链接,这也会大量消耗服务器带宽和资源。

面对这种状况,HTML5定义了WebSocket协议,能更好的节省服务器资源和带宽并达到实时通讯。

优点

Header

服务器与客户端之间交换的标头信息很小,大概只有2字节。(早期版本)

服务器推送

服务器可以主动传送数据给客户端。(试想一下,如果服务器在早晨会自启动并发送数据到那些希望接收而不用提前建立一些连接端口的客户端,这是一件多棒的事情啊!欢迎来到PUSH技术的世界!)

第三步:开始创建客户端

  下面来创建基本模板,这是我的client.php文件:

<!DOCTYPE html>  
<html>  
<head>  
<script src="js/jquery.min.js"></script>  
  
<title>WebSockets Client</title>  
  
</head>  
<body>  
<div id="wrapper">  
  
    <div id="container">  
  
        <h1>WebSockets Client</h1>  
  
        <div id="chatLog">  
  
        </div><!-- #chatLog -->  
        <p id="examples">e.g. try ‘hi‘, ‘name‘, ‘age‘, ‘today‘</p>  
  
        <input id="text" type="text" />  
        <button id="disconnect">Disconnect</button>  
  
    </div><!-- #container -->  
  
</div>  
</body>  
</html>

  我们已经创建里基本模板:一个chat log容器,一个input输入框和一个断开连接的按钮。

添加一些CSS

  没什么花俏代码,只是处理一下标签的样式。

body {  
    font-family:Arial, Helvetica, sans-serif;  
}  
#container{  
    border:5px solid grey;  
    width:800px;  
    margin:0 auto;  
    padding:10px;  
}  
#chatLog{  
    padding:5px;  
    border:1px solid black;  
}  
#chatLog p {  
    margin:0;  
}  
.event {  
    color:#999;  
}  
.warning{  
    font-weight:bold;  
    color:#CCC;  
}

WebSocket事件

首先让我们尝试并理解WebSocket事件的概念:

WebSocket事件:
我们将使用三个WebSocket事件:
onopen: 当接口打开时
onmessage: 当收到信息时
onclose: 当接口关闭时

我们如何来实现呢?
首先创建WebSocket对象

//需将服务器监听端口改为8000
var socket = new WebSocket("ws://localhost:8000/socket/server/startDaemon.php")

然后向下面这样检测事件

socket.onopen = function(){  
    alert("Socket has been opened!");  
}

当我们收到信息时这样做:

socket.onmessage = function(msg){  
    alert(msg); //Awesome!  
}

但我们还是尽量避免使用alert,现在我们可以把我们学的东西整合到客户端页面中了。

JavaScript

首先我们将代码放到jQuery 的 document.ready函数中,然后我们还要检查用户的浏览器是否支持WebSocket。如果不支持,我们就添加一个链向Chrome浏览器页面的链接。

$(document).ready(function() {  
    if(!("WebSocket" in window)){  
        $(‘#chatLog, input, button, #examples‘).fadeOut("fast");  
        $(‘<p>Oh no, 
you need a browser that supports WebSockets. How about <a 
href="http://www.google.com/chrome">Google 
Chrome</a>?</p>‘).appendTo(‘#container‘);  
    }else{  
  
    //The user has WebSockets  
  
    connect();  
  
    function connect(){  
        //the connect function code is below  
  
    }  
});

如你所见,如果用户浏览器支持WebSocket,我们将执行connect()函数。这里是核心功能,我们将开始创建open、close和receive事件。

我们将在我们的服务器定义URL。

var socket;  
var host = "ws://localhost:8000/socket/server/startDaemon.php";

你可能会发现URL中怎么没有http?恩,是的,这是一个WebSocket URL,使用了不同的协议。下面是URL分解图示:

  下面让我们继续完成connect()函数,我们将代码放入try/catch块,这样如果代码出现问题,我们能让用户知道。我们创建 WebSocket,并将信息传递到message()函数,之后会做讲解。我们创建我们的onopen、onmessage和onclose函数. 需要注意的是我们为用户提供了端口状态,这并不是必需的,但我们把它放进来主要是为了方便调试。

CONNECTING = 0
OPEN = 1
CLOSED = 2

function connect(){  
    try{  
  
    var socket;  
    var host = "ws://localhost:8000/socket/server/startDaemon.php";  
    var socket = new WebSocket(host);  
  
        message(‘<p class="event">Socket Status: ‘+socket.readyState);  
  
        socket.onopen = function(){  
             message(‘<p class="event">Socket Status: ‘+socket.readyState+‘ (open)‘);  
        }  
  
        socket.onmessage = function(msg){  
             message(‘<p class="message">Received: ‘+msg.data);  
        }  
  
        socket.onclose = function(){  
             message(‘<p class="event">Socket Status: ‘+socket.readyState+‘ (Closed)‘);  
        }             
  
    } catch(exception){  
         message(‘<p>Error‘+exception);  
    }  
}

message()函数很简单, 它将我们想展现给用户的文本填入chat log容器内。 我们在socket事件函数中为段落(<p>)标签创建适当的class,我们在message函数中只有一个段落结束标签。

function message(msg){  
    $(‘#chatLog‘).append(msg+‘</p>‘);  
}

目前的成果

  如果你已按上面教程按部就班的做的话,很好,我们已经创建了 HTML/CSS 模板、创建并建立Websocket连接、通过创建连接保持用户的进展更新。

第七步:发送数据

  现在我们已经有了提交按钮,但我们还需要监听用户按下键盘的事件,并运行send函数,下面的’13′便是回车键对应的ASCII码。

$(‘#text‘).keypress(function(event) {  
    if (event.keyCode == ‘13‘) {  
        send();  
    }  
});

下面是send()函数:

function send(){  
  
    var text = $(‘#text‘).val();  
    if(text==""){  
        message(‘<p class="warning">Please enter a message‘);  
        return ;  
    }  
    try{  
        socket.send(text);  
        message(‘<p class="event">Sent: ‘+text)  
    } catch(exception){  
    message(‘<p class="warning"> Error:‘ + exception);  
    }  
  
    $(‘#text‘).val("");  
  
}

下面我们需要:

socket.send();

  那些额外的代码做了以下工作:检测用户是否什么都没输入却仍点击返回、清空input输入框、执行message()函数。

关闭Socket

  关闭Socket操作相当简单,添加对断开连接按钮的click事件监听就可以。

$(‘#disconnect‘).click(function(){  
    socket.close();  
});

完整JavaScript代码

$(document).ready(function() {  
  
  if(!("WebSocket" in window)){  
  $(‘#chatLog, input, button, #examples‘).fadeOut("fast");  
  $(‘<p>Oh no, you need
 a browser that supports WebSockets. How about <a 
href="http://www.google.com/chrome">Google 
Chrome</a>?</p>‘).appendTo(‘#container‘);  
  }else{  
      //The user has WebSockets  
  
      connect();  
  
      function connect(){  
          var socket;  
          var host = "ws://localhost:8000/socket/server/startDaemon.php";  
  
          try{  
              var socket = new WebSocket(host);  
  
              message(‘<p class="event">Socket Status: ‘+socket.readyState);  
  
              socket.onopen = function(){  
                 message(‘<p class="event">Socket Status: ‘+socket.readyState+‘ (open)‘);  
              }  
  
              socket.onmessage = function(msg){  
                 message(‘<p class="message">Received: ‘+msg.data);  
              }  
  
              socket.onclose = function(){  
                message(‘<p class="event">Socket Status: ‘+socket.readyState+‘ (Closed)‘);  
              }           
  
          } catch(exception){  
             message(‘<p>Error‘+exception);  
          }  
  
          function send(){  
              var text = $(‘#text‘).val();  
  
              if(text==""){  
                  message(‘<p class="warning">Please enter a message‘);  
                  return ;  
              }  
              try{  
                  socket.send(text);  
                  message(‘<p class="event">Sent: ‘+text)  
  
              } catch(exception){  
                 message(‘<p class="warning">‘);  
              }  
              $(‘#text‘).val("");  
          }  
  
          function message(msg){  
            $(‘#chatLog‘).append(msg+‘</p>‘);  
          }  
  
          $(‘#text‘).keypress(function(event) {  
              if (event.keyCode == ‘13‘) {  
                send();  
              }  
          });     
  
          $(‘#disconnect‘).click(function(){  
             socket.close();  
          });  
  
      }//End connect  
  
  }//End else  
  
});
时间: 2024-10-10 22:13:53

websockets学习笔记(一)的相关文章

vector 学习笔记

vector 使用练习: /**************************************** * File Name: vector.cpp * Author: sky0917 * Created Time: 2014年04月27日 11:07:33 ****************************************/ #include <iostream> #include <vector> using namespace std; int main

Caliburn.Micro学习笔记(一)----引导类和命名匹配规则

Caliburn.Micro学习笔记(一)----引导类和命名匹配规则 用了几天时间看了一下开源框架Caliburn.Micro 这是他源码的地址http://caliburnmicro.codeplex.com/ 文档也写的很详细,自己在看它的文档和代码时写了一些demo和笔记,还有它实现的原理记录一下 学习Caliburn.Micro要有MEF和MVVM的基础 先说一下他的命名规则和引导类 以后我会把Caliburn.Micro的 Actions IResult,IHandle ICondu

jQuery学习笔记(一):入门

jQuery学习笔记(一):入门 一.JQuery是什么 JQuery是什么?始终是萦绕在我心中的一个问题: 借鉴网上同学们的总结,可以从以下几个方面观察. 不使用JQuery时获取DOM文本的操作如下: 1 document.getElementById('info').value = 'Hello World!'; 使用JQuery时获取DOM文本操作如下: 1 $('#info').val('Hello World!'); 嗯,可以看出,使用JQuery的优势之一是可以使代码更加简练,使开

[原创]java WEB学习笔记93:Hibernate学习之路---Hibernate 缓存介绍,缓存级别,使用二级缓存的情况,二级缓存的架构集合缓存,二级缓存的并发策略,实现步骤,集合缓存,查询缓存,时间戳缓存

本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱好者,互联网技术发烧友 微博:伊直都在0221 QQ:951226918 -----------------------------------------------------------------------------------------------------------------

Activiti 学习笔记记录(三)

上一篇:Activiti 学习笔记记录(二) 导读:上一篇学习了bpmn 画图的常用图形标记.那如何用它们组成一个可用文件呢? 我们知道 bpmn 其实是一个xml 文件

HTML&CSS基础学习笔记8-预格式文本

<pre>标签的主要作用是预格式化文本.被包围在 pre 标签中的文本通常会保留空格和换行符.而文本也会呈现为等宽字体. <pre>标签的一个常见应用就是用来表示计算机的源代码.当然你也可以在你需要在网页中预显示格式时使用它. 会使你的文本换行的标签(例如<h>.<p>)绝不能包含在 <pre> 所定义的块里.尽管有些浏览器会把段落结束标签解释为简单地换行,但是这种行为在所有浏览器上并不都是一样的. 更多学习内容,就在码芽网http://www.

java/android 设计模式学习笔记(14)---外观模式

这篇博客来介绍外观模式(Facade Pattern),外观模式也称为门面模式,它在开发过程中运用频率非常高,尤其是第三方 SDK 基本很大概率都会使用外观模式.通过一个外观类使得整个子系统只有一个统一的高层的接口,这样能够降低用户的使用成本,也对用户屏蔽了很多实现细节.当然,在我们的开发过程中,外观模式也是我们封装 API 的常用手段,例如网络模块.ImageLoader 模块等.其实我们在开发过程中可能已经使用过很多次外观模式,只是没有从理论层面去了解它. 转载请注明出处:http://bl

[原创]java WEB学习笔记48:其他的Servlet 监听器:域对象中属性的变更的事件监听器 (3 个),感知 Session 绑定的事件监听器(2个)

本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱好者,互联网技术发烧友 微博:伊直都在0221 QQ:951226918 ---------------------------------

java/android 设计模式学习笔记(10)---建造者模式

这篇博客我们来介绍一下建造者模式(Builder Pattern),建造者模式又被称为生成器模式,是创造性模式之一,与工厂方法模式和抽象工厂模式不同,后两者的目的是为了实现多态性,而 Builder 模式的目的则是为了将对象的构建与展示分离.Builder 模式是一步一步创建一个复杂对象的创建型模式,它允许用户在不知道内部构建细节的情况下,可以更精细地控制对象的构造流程.一个复杂的对象有大量的组成部分,比如汽车它有车轮.方向盘.发动机.以及各种各样的小零件,要将这些部件装配成一辆汽车,这个装配过