H5新特性websocket

websocket也是html5的新增加内容之一,号称是下一代客户端/服务器异步通信办法,私以为虽然有点吹牛的成分,但是以后说不定能成为异步通信的半壁江山,至于取代ajax,我觉的应该不会。

websocket的一个很有意思的特点就是双向通信,这一点其实也不稀奇,跟socket一样的。

下边是websocket的原理性知识总结是写给我自己看的,如果你没兴趣,可以跳过直接到代码:

tcp建立连接tcp连接的建立需要经历”三次握手“的过程。过程如下client发送SYN包(值为j)以及SEQ包到server端,此时client进入SYN_SEND状态。此为第一次握手。server端收到SYN包后,发送一个ACK(值为seq+1)确认包和SYN(值为k)给client,此时server进入SYN_RECV状态。此为第二次握手。client收到SYN+ACK包后,向server发送一个ACK(值为k+1),该包发送完成后,client和server均进入ESTABLISH状态。此为第三次握手。

client和server两端状态变化如下:

client:

CLOSED->SYN_SEND->ESTABLISH

server:

CLOSED->LISTEN->SYN_RECV->ESTABLISH

tcp是传输层的协议,tcp三次握手后,应用层协议http也便建立了连接。而对于当今web的发展情况,http仍有许多瓶颈。

一条连接只能发送一个请求。
请求只能从客户端开始。客户端不可以接收除响应以外的指令。
请求/响应首部未经压缩发送,首部信息越多延迟越大。
发送冗长的首部。每次互相发送相同的首部造成较多的浪费。
可任意选择数据压缩格式。非强制压缩发送。
虽然已经出现了很多解决方案,如ajax、comet,但是他们最终使用的都是http协议,因此也无法从根本上解决这些瓶颈。

因此也就诞生了一个新的通信协议,WebSocket协议,一种全双工通信协议

该通信协议建立在http协议的基础之上,因此连接的发起方仍然是客户端,在http连接建立之后,再将协议升级为webSocket连接,在webSocket连接建立之后,客户度和服务器端都可以主动向对方发送报文信息了。

建立webSocket连接,需要先建立http连接,并在此基础上再进行一次”握手“。

client会发起一个”握手“的请求,请求首部含有upgrade:websocket(还有其他首部,具体看如下示例)。服务器端返回一个101状态码,确认转换协议。完成握手后便可以使用websocket协议进行通信。

Client(request)

GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: AQIDBAUGBwgJCgsMDQ4PEC==
Origin: http://example.com
Sec-WebSocket-protocol: chat, superchat
Sec-WebSocket-Version: 13

server (response)

HTTP/1.1 101 switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Protocol: chat

websocket这个协议涉及前端显示,以及服务器处理,我这里使用基础的java+js来实现一个简单的群聊

 1 package example;
 2
 3 import java.io.IOException;
 4 import java.util.Set;
 5 import java.util.concurrent.CopyOnWriteArraySet;
 6
 7 import javax.websocket.OnClose;
 8 import javax.websocket.OnError;
 9 import javax.websocket.OnMessage;
10 import javax.websocket.OnOpen;
11 import javax.websocket.Session;
12 import javax.websocket.server.PathParam;
13 import javax.websocket.server.ServerEndpoint;
14
15
16 @ServerEndpoint(value="/ws/chat/{nickName}")
17 public class Chat {
18     private static final Set<Chat> connections = new CopyOnWriteArraySet<Chat>();
19     private String nickName; //接收用户名称
20     private Session session; //建立的会话
21
22
23     public Chat(){
24
25     }
26
27     /*
28      * 打开连接
29      */
30     @OnOpen
31     public void onOpen(Session session,@PathParam(value="nickName") String nickName){
32         this.session=session;
33         this.nickName=nickName;
34         connections.add(this);
35         System.out.println("新用户连接进入,名字是:"+this.nickName);
36         String message=String.format("System>%s %s",this.nickName,"hasjoined.");
37         Chat.broadCast(message);
38
39     }
40     /*
41      * 关闭连接
42      */
43     @OnClose
44     public void onClose(){
45         connections.remove(this);
46         String message=String.format("System> %s, %s", this.nickName,
47                 " has disconnection.");
48         Chat.broadCast(message);
49     }
50
51     /*
52      * 接收信息
53      */
54     @OnMessage
55     public void onMessage(String message,@PathParam(value="nickName")String nickName){
56         System.out.println("新消息from:"+nickName+" : "+message);
57         Chat.broadCast(nickName+">"+message);
58     }
59     /*
60      * 错误消息
61      */
62     @OnError
63     public void onError(Throwable throwable){
64         System.out.println(throwable.getMessage());
65     }
66     /*
67      * 广播消息
68      */
69     private static void broadCast(String message){
70         for(Chat chat:connections){
71             try{
72                 synchronized (chat) { //线程同步控制并发访问
73                     chat.session.getBasicRemote().sendText(message);
74                 }
75             }catch(IOException e){
76                 connections.remove(chat);
77                 try{
78                     chat.session.close();
79
80                 }catch(IOException e1){
81                     chat.broadCast(String.format("System> %s %s", chat.nickName,
82                             " has bean disconnection."));
83                 }
84             }
85         }
86     }
87 }


 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4 <meta charset="utf-8"/>
 5 <title>Testing websockets</title>
 6 </head>
 7 <body>
 8   <div>
 9       <input type="text" id="yourName"/>
10     <button id="start">click to start</button>
11   </div>
12   <div style="width:100%;">
13       <div id="messages" style="border:5px solid red;width:50%;height:300px;margin-top:20px;"></div>
14   </div>
15   <div style="width:100%;margin-top:20px;">
16       <div id="sends" style="float:left;width:50%;height:50px;margin-right:20px;">
17           <input type="text"  id="MessageUN" style="width:100%;height:48px;"/>
18       </div>
19       <button style="float:left;width:10%;height:50px;" id="sendMessage">发送</button>
20   </div>
21
22   <script type="text/javascript">
23   var button=document.getElementById("start");
24   button.onclick=function(){
25
26
27
28
29       var name=document.getElementById("yourName");
30       console.log(name.value);
31       var websocketAdd="ws://localhost:8080/t8j8/ws/chat/"+name.value;
32       var webSocket=new WebSocket(websocketAdd);
33
34
35       function onMessage(event) {
36             document.getElementById(‘messages‘).innerHTML
37               += ‘<br />‘ + event.data;
38       }
39
40       function onOpen(event) {
41             document.getElementById(‘messages‘).innerHTML
42               = ‘Connection established‘;
43           //一旦链接开始,尝试发出一条通讯消息
44              start();
45           alert("消息通道开启,可以发送消息了");
46           //确认链接开始,就可以开始消息的发送了
47           //首先绑定一个点击事件
48           var sendMessage=document.getElementById("sendMessage");
49           sendMessage.onclick=function(){
50               var message= document.getElementById(‘MessageUN‘).value;
51               //我们之前会有一个唯一的标识符,就是在click to start之前的标识符
52               webSocket.send(message);
53               //上边一部完成之后,会自动触发onmessage事件
54           }
55
56       }
57
58
59        function start() {
60          webSocket.send(name.value+" : "+‘hello‘);
61        }
62
63       function onError(event) {
64             alert(event.data);
65       }
66
67       webSocket.onerror = function(event) {
68             onError(event)
69       };
70
71       webSocket.onopen = function(event) {
72             onOpen(event)
73       };
74
75       webSocket.onmessage = function(event) {
76             onMessage(event)
77       };
78
79   }
80
81   </script>
82 </body>
83 </html>

重要的只有两个文件:chat.java以及chat.html,实现的是一个微型聊天室,当有用户连接近来和发送消息,所有都能看到。

 
 
时间: 2024-10-19 18:06:27

H5新特性websocket的相关文章

H5 新特性之全局属性一

<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Title</title></head><body> <!--<!DOCTYPE html>--><!--<html lang="en">--><!--<he

H5新特性之语义化标签

二月底,疫情仍未过去,在家逆战学习. 说道H5新特性的语义化标签,就不得不先简单说一下它的发展史,兼容和一些语法问题. H5在经过多达近百项的修改,包括HTML和XHTML的标签,相关的API,Canvas等,性 能得到进一步提升. H5仅仅是新增添了一些内容并优化了它们,而不是全盘否定之前的旧的内容.支持Html5 的浏览器包括Firefox(火狐浏览器),IE9及其更高版本,Chrome(谷歌浏览器),Safari, Opera等以及一些国内浏览器. 对于H5语法变化不大,文件的扩展名是不变

前端面试基础-html篇之H5新特性

h5的新特性(目前个人所了解)如下 语义化标签 表单新特性 视频(video)和音频(audio) canvas画布 svg绘图 地理定位 为鼠标提供的拖放API webworker (重点)Storage (重点)Websocket HTML语义化是什么? 语义化是指根据内容的结构化(内容语义化),选择合适的标签(代码语义化),便于开发者阅读和写出更优雅的代码的同时,让浏览器的爬虫和机器很好的解析. 为什么要语义化? 有利于SEO,有助于爬虫抓取更多的有效信息,爬虫是依赖于标签来确定上下文和各

h5新特性

  CSDN博客 Gane_Cheng HTML5新特性浅谈 发表于2016/10/17 21:25:58  7809人阅读 分类: 前端 转载请注明出处: http://blog.csdn.net/gane_cheng/article/details/52819118 http://www.ganecheng.tech/blog/52819118.html (浏览效果更好) 2014年10月29日,W3C宣布,经过接近8年的艰苦努力,HTML5标准规范终于制定完成. HTML5将会取代

h5新特性 File API详解

之前一直觉得h5的新特性就是一些新标签呢,直到想研究一下图片上传预览的原理,才发现还是有好多新的api的,只是不兼容ie低版本,挺可惜的, File API在表单中文件输入字段基础上,又添加了一些直接访问文件信息的接口.H5在DOM中为文件输入元素添加了一个files集合,在通过表单元素选择了一个或多个文件时,files集合中将包含一组file对象,每个file对象对应一个文件,每个file对象都有下列只读属性: 1.name:本地文件系统的文件名: 2.size:文件的字节大小: 3.type

H5新特性之data-*

简单介绍:html5的data-*能够为标签添加一些自定义的属性和值,并且这种自定义的属性和值可以通过js来获取,十分的便捷 代码: //html代码<tr th:each="plan : ${list}" th:id="${plan.planId}" th:attr="data-plan-status=${plan.planStatus},data-name=${plan.planName}"> <td></td&

H5新特性总结

Web前端最新的官方标准无疑就是es6和H5了,es6之前已经说过了(多是一些语法糖),现在来总结一下H5给我们来了哪些新"朋友"吧~ 1.video/radio  视频/音频 2.canvas 绘画 3.geolocation 定位 4.WebSocket 前后端双向通讯 5.localStorage/sessionStorage代替cookie本地存储 6.文件拖拽(drag事件+dataTransfer+FileReader) 7.WebWorker js多线程,提高性能 8.W

H5新特性:

新增选择器 document.querySelector.document.querySelectorAll 拖拽释放(Drag and drop) API 媒体播放的 video 和 audio 本地存储 localStorage 和 sessionStorage 离线应用 manifest 桌面通知 Notifications 语意化标签 article.footer.header.nav.section 增强表单控件 calendar.date.time.email.url.search

H5新特性&#183;语义化标签

所谓[语义化],便是[见名知意]! 在笔者基础阶段学习搭建页面结构的过程中,常常使用div划分页面结构,通过给div命名才能大概知晓每个模块的功能: 而H5语义化标签的出现与补充,解决了困扰笔者的这一问题:使得页面结构的搭建,不再复杂,每个版块的功能都清晰可见>>>(*^▽^*) 下面就让我们一起看看,新添加了哪些强大的语义化标签吧!!! [借鉴出处]http://caibaojian.com/html5/ele.html 笔者也亲自验证了一部分,如下图: ①[局部]time标签的使用,